<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: StepZen</title>
    <description>The latest articles on Forem by StepZen (@stepzen).</description>
    <link>https://forem.com/stepzen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3943%2Faf485a9e-2bd8-4dbd-97d0-b998e5adcc0c.png</url>
      <title>Forem: StepZen</title>
      <link>https://forem.com/stepzen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/stepzen"/>
    <language>en</language>
    <item>
      <title>How to Build Angular Search Functionality with GraphQL?</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Mon, 27 Mar 2023 12:46:11 +0000</pubDate>
      <link>https://forem.com/stepzen/how-to-build-angular-search-functionality-with-graphql-31kb</link>
      <guid>https://forem.com/stepzen/how-to-build-angular-search-functionality-with-graphql-31kb</guid>
      <description>&lt;p&gt;In this tutorial, you will learn how to build a fullstack Angular application that uses GraphQL to fetch data from a server. The application we'll build together will display a list of blog posts fetched from a GraphQL API using Apollo Client, including search functionality. To create the GraphQL API, we will use StepZen, a GraphQL API platform that allows you to build and deploy a GraphQL API in minutes.&lt;/p&gt;

&lt;p&gt;Do you prefer watching a video walkthrough instead? Check out the link below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/Cuh79sEvWqI"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hqIodK_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.ytimg.com/vi/Cuh79sEvWqI/hqdefault.jpg" alt="Watch a video walkthrough of Getting Started With GraphQL in Angular using StepZen" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Google has developed Angular, an open-source web application framework based on TypeScript. The initial release of Angular from angular.js involved a complete rewrite, enabling the creation of large-scale, cross-platform applications.&lt;/p&gt;

&lt;p&gt;Angular has gained a reputation for its exceptional developer tooling, which includes built-in features such as TypeScript support, routing, and a command-line interface. Additionally, Angular's component-based architecture, remarkable speed and performance, and other powerful features make it a popular choice among developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow this tutorial, you will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://nodejs.org/en/download/"&gt;Node.js&lt;/a&gt; installed on your machine&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://cli.angular.io/"&gt;Angular CLI&lt;/a&gt; installed on your machine (you can install it globally by running the following command using npm: &lt;code&gt;npm install -g @angular/cli&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://stepzen.com/docs/quickstart"&gt;StepZen CLI&lt;/a&gt; installed on your machine (you can install it globally by running the following command using npm: &lt;code&gt;npm install -g stepzen&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You can find the source code for this tutorial on &lt;a href="https://github.com/stepzen-dev/examples/tree/main/with-angular"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setting up a new Angular project
&lt;/h2&gt;

&lt;p&gt;To build an Angular application, we will use the Angular CLI. The Angular CLI is a command-line interface that allows you to create, build, and test Angular applications.&lt;/p&gt;

&lt;p&gt;If you don't have the Angular CLI already on your machine, you can install it globally by running the following command using npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: The Angular CLI requires a minimum Node.js version of either v14.20, v16.13, or v18.10. With the Angular CLI installed, we can now create a new Angular application by running the following command:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;ng new with-angular &lt;span class="nt"&gt;--directory&lt;/span&gt; ./with-angular&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a new Angular application named &lt;code&gt;with-angular&lt;/code&gt;, and we specified the directory where the application will be created with the'-- directory' flag. The Angular CLI will create a new directory named &lt;code&gt;with-angular&lt;/code&gt; if it doesn't exist and will create the application inside the directory.&lt;/p&gt;

&lt;p&gt;After the Angular CLI has finished creating the application, we can now navigate to the application directory and start the development server by running the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;with-angular
ng serve &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ng serve&lt;/code&gt; command will start the development server, and the &lt;code&gt;--open&lt;/code&gt; flag will open the application in the default browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7xxkUSCK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/starter-angular-application.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7xxkUSCK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/starter-angular-application.png" alt="The starter Angular application" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the starter application running, we can now start building our application. But before we can start building the application, we need to create a GraphQL API that we can use to fetch data. In the next section, we'll create a GraphQL API using StepZen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a GraphQL API with StepZen
&lt;/h2&gt;

&lt;p&gt;The Angular application we build in this blog post will fetch data from a GraphQL API. To create a GraphQL API, we will use StepZen, a GraphQL API platform that allows you to build and deploy a GraphQL API in minutes. One of the capabilities of StepZen is transforming REST APIs into GraphQL APIs, which will be demonstrated in this tutorial.&lt;/p&gt;

&lt;p&gt;Before creating a GraphQL API, we need to create a StepZen account. You can create a free account by visiting the &lt;a href="https://stepzen.com/signup"&gt;StepZen website&lt;/a&gt;. And once you've created an account, you can install the StepZen CLI (if you haven't already) by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; stepzen&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the StepZen CLI installed, we can now create a new StepZen project in the &lt;code&gt;with-angular&lt;/code&gt; directory by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;stepzen
stepzen init &lt;span class="nt"&gt;--endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;api/with-angular
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The blog posts we want to show in our application are fetched from the &lt;a href="https://dev.to/"&gt;DEV.to&lt;/a&gt; API. More specifically, we will fetch the posts from the DEV.to API's &lt;code&gt;articles&lt;/code&gt; endpoint: &lt;code&gt;https://dev.to/api/articles?username=gethackteam&lt;/code&gt;. The &lt;code&gt;articles&lt;/code&gt; endpoint returns a list of articles, and you could provide a different username to fetch articles from another user.&lt;/p&gt;

&lt;p&gt;To create a GraphQL API that fetches data from the DEV.to API, we can use the &lt;code&gt;import&lt;/code&gt; command from the StepZen CLI. This command will create a GraphQL schema for this REST API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;stepzen import curl &lt;span class="s1"&gt;'https://dev.to/api/articles?username=gethackteam'&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;posts &lt;span class="nt"&gt;--query-type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Posts &lt;span class="nt"&gt;--query-name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;posts&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which generates a new GraphQL schema in a directory named &lt;code&gt;posts&lt;/code&gt;, which has a query called &lt;code&gt;posts&lt;/code&gt; that returns a list of posts. The &lt;code&gt;--query-type&lt;/code&gt; flag specifies the name of the type that the query will return, and the &lt;code&gt;--query-name&lt;/code&gt; flag specifies the query's name.&lt;/p&gt;

&lt;p&gt;From a different DEV.to endpoint, we want to retrieve a single post by its ID to retrieve a list of posts. To do this, we can use the &lt;code&gt;import&lt;/code&gt; command again, but this time we'll use the &lt;code&gt;--query-type&lt;/code&gt; and &lt;code&gt;--query-name&lt;/code&gt; flags with different values to specify the name of the type and query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;stepzen import curl &lt;span class="s1"&gt;'https://dev.to/api/articles/1366695'&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;post &lt;span class="nt"&gt;--query-type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Post &lt;span class="nt"&gt;--query-name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;post&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There might be some overlap between type names when importing multiple REST APIs using &lt;code&gt;stepzen import curl&lt;/code&gt;. The StepZen CLI will notify you of this, and you can manually delete the duplicated types from the GraphQL schemas. For this project, we can delete the &lt;code&gt;User&lt;/code&gt;, and &lt;code&gt;Organization&lt;/code&gt; types from the file &lt;code&gt;post/index.graphql&lt;/code&gt; as these were already specified in the schema for the first import.&lt;/p&gt;

&lt;p&gt;To deploy the GraphQL API, we can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;stepzen start&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will deploy the GraphQL API to the StepZen cloud. Once the GraphQL API is deployed, you explore the GraphQL API from the Explorer in the StepZen dashboard by visiting the following URL: &lt;a href="https://dashboard.stepzen.com/explorer?endpoint=api%2Fwith-angular%2F__graphql"&gt;https://dashboard.stepzen.com/explorer?endpoint=api%2Fwith-angular%2F__graphql&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From the Explorer, you can run queries and mutations against the GraphQL API. For example, you can run the following query to retrieve a list of posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GetPosts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also search for articles from a specific user by changing the &lt;code&gt;username&lt;/code&gt; parameter in the query, as shown in the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GPwGKbFG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/angular-application-graphql-explorer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GPwGKbFG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/angular-application-graphql-explorer.png" alt="The StepZen Explorer" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the GraphQL API deployed, we can now start building our Angular application. In the next section, we'll add Apollo Client to our Angular application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Apollo Client to our Angular application
&lt;/h2&gt;

&lt;p&gt;Install Apollo Client for Angular&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;ng add apollo-angular&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We're using the Angular CLI to add the library &lt;code&gt;apollo-angular&lt;/code&gt; rather than npm, as this will autogenerate some of the boilerplate code to set up Apollo Client. The Angular CLI will prompt you for the endpoint of your GraphQL API, which you can answer with the endpoint of your GraphQL API that you deployed in the previous step. The endpoint of your GraphQL API is printed in the terminal after running &lt;code&gt;stepzen start&lt;/code&gt;, and will look something like this: &lt;code&gt;https://YOUR_USERNAME.stepzen.com/with-angular/__graphql&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once entering your GraphQL API endpoint and the GraphQL version (you can use the suggested one), the Angular CLI will generate the setup files for Apollo Client and reference it in the entry point of your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CREATE src/app/graphql.module.ts &lt;span class="o"&gt;(&lt;/span&gt;713 bytes&lt;span class="o"&gt;)&lt;/span&gt;
UPDATE package.json &lt;span class="o"&gt;(&lt;/span&gt;1128 bytes&lt;span class="o"&gt;)&lt;/span&gt;
UPDATE tsconfig.json &lt;span class="o"&gt;(&lt;/span&gt;895 bytes&lt;span class="o"&gt;)&lt;/span&gt;
UPDATE src/app/app.module.ts &lt;span class="o"&gt;(&lt;/span&gt;462 bytes&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These steps complete the installation of Apollo Client but don't handle the data fetching part yet. The next section will add a new Angular component and fetch data from the GraphQL API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching data with Apollo Client
&lt;/h2&gt;

&lt;p&gt;The query we'll use to display the blog posts is the same one we created in the first part of this blog post. You need to create a new file called &lt;code&gt;graphql.operations.ts&lt;/code&gt; in the &lt;code&gt;app&lt;/code&gt; directory and add the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo-angular&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
    query GetPosts {
        posts {
        id
        title
        description
        }
    }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And use the Angular CLI to generate the boilerplate files for a new component called &lt;code&gt;posts&lt;/code&gt; in the &lt;code&gt;app&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;ng generate component posts &lt;span class="nt"&gt;--module&lt;/span&gt; app&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Angular CLI will create a new directory called &lt;code&gt;posts&lt;/code&gt; with the files for the business logic (&lt;code&gt;*.ts&lt;/code&gt;), styling (&lt;code&gt;*.css&lt;/code&gt;), markup (&lt;code&gt;*.html&lt;/code&gt;), and testing (&lt;code&gt;*.spec.ts&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;To add the logic to fetch the data from the GraphQL API, you can replace the code in &lt;code&gt;posts/posts.component.ts&lt;/code&gt; with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Apollo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo-angular&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../graphql.operations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./posts.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./posts.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostsComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;apollo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Apollo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apollo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;watchQuery&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;valueChanges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we also need to add the styling and markup to render the posts in the application. In &lt;code&gt;posts.component.html&lt;/code&gt; and &lt;code&gt;posts.component.css&lt;/code&gt;, let's add the following HTML and CSS:&lt;/p&gt;

&lt;p&gt;Add the following HTML code in &lt;code&gt;posts.component.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Error: {{ error }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"posts-container"&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"posts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;*ngFor= &lt;/span&gt;&lt;span class="s"&gt;"let post of posts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ post.title }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ post.description }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the following CSS in &lt;code&gt;posts.component.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.posts-container&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.posts-container&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#e0e0e0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.post&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.post-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.post-description&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; To render the posts in the application, we need to add &lt;code&gt;app-posts&lt;/code&gt; (the selector from &lt;code&gt;PostsComponent&lt;/code&gt;) to the &lt;code&gt;app.component.html&lt;/code&gt; file. In this file, replace the content with the following:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"banner"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://stepzen.comdata:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;My posts&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;app-posts&amp;gt;&amp;lt;/app-posts&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; Finally, add styling to the &lt;code&gt;app.component.css&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1976d2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application should now look like this; make sure to run &lt;code&gt;npm start&lt;/code&gt; to start the development server:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M7VqL-qY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/graphql-angular-application.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M7VqL-qY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/graphql-angular-application.png" alt="Fetching GraphQL in an Angular application" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But that's not all. You can also search posts by username. In the next section, we'll extend the functionality of this application by adding a search bar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding search functionality
&lt;/h2&gt;

&lt;p&gt;In this section, we'll add a search bar to the application to search for posts by username. With this functionality, we can search for posts by a specific user.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; For starters, we will add a new query to the &lt;code&gt;graphql.operations.ts&lt;/code&gt; file. This query will take a username as an argument and return the same fields as the &lt;code&gt;GET_POSTS&lt;/code&gt; query:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS_BY_USERNAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
    query GetPostsByUsername($username: String!) {
        posts(username: $username) {
            id
            title
            description
        }
  }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS_BY_USERNAME&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; From the file &lt;code&gt;posts/posts.component.ts&lt;/code&gt;, we first need to import the built-in forms library &lt;code&gt;@angular/forms&lt;/code&gt; and the &lt;code&gt;GET_POSTS_BY_USERNAME&lt;/code&gt; query:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormControl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormGroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Apollo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo-angular&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS_BY_USERNAME&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../graphql.operations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; In the same file, we will add a new method called &lt;code&gt;searchPosts&lt;/code&gt; that will be called when the user submits the search form. This method will take the &lt;code&gt;GET_POSTS_BY_USERNAME&lt;/code&gt; query and pass the username as an argument. The data for &lt;code&gt;posts&lt;/code&gt; will be overwritten with the new data:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostsComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;searchForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormGroup&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gethackteam&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;searchPosts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apollo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GET_POSTS_BY_USERNAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; To add the search bar, we will add a &lt;code&gt;form&lt;/code&gt; element to the markup file &lt;code&gt;posts.component.html&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Error: {{ error }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt; &lt;span class="na"&gt;[formGroup]=&lt;/span&gt;&lt;span class="s"&gt;"searchForm"&lt;/span&gt; &lt;span class="na"&gt;(ngSubmit)=&lt;/span&gt;&lt;span class="s"&gt;"searchPosts()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Enter username"&lt;/span&gt; &lt;span class="na"&gt;formControlName=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"submit-button"&lt;/span&gt; &lt;span class="na"&gt;[disabled]=&lt;/span&gt;&lt;span class="s"&gt;"searchForm.invalid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;SUBMIT&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; And to complete the search functionality, you can add the following styling rules to the bottom of the file &lt;code&gt;posts.component.css&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"text"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;7px&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#E23237&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#FFF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you go to the Angular application running in your browser on &lt;code&gt;localhost&lt;/code&gt; you can now search by username. A placeholder username is already present, and you can press the "submit" button to search for posts written by this username. Or, replace this value with your own username.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CMoYccgC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/graphql-angular-application-with-search.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CMoYccgC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/graphql-angular-application-with-search.png" alt="Search for posts with an username" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congrats on building a fullstack Angular application! The final application should look something like the screenshot above. You can add features like error and loading status or routing to display an individual post to continue learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This tutorial taught you to use GraphQL in an Angular application using Apollo Client. With Angular, you can build scalable frontend applications with native TypeScript support. On the other hand, Apollo Client is a library to help you fetish data from a GraphQL API. For example, the GraphQL API you created in this tutorial by transforming the DEV.to REST API into GraphQL using StepZen.&lt;/p&gt;

&lt;p&gt;Head over to our &lt;a href="https://github.com/stepzen-dev/examples"&gt;examples repository&lt;/a&gt; for more examples of using GraphQL and frontend libraries. Or the &lt;a href="https://stepzen.com/docs/quick-start"&gt;StepZen docs&lt;/a&gt; to learn more about building GraphQL APIs? If you have questions about this tutorial, you can ask for help on our &lt;a href="https://discord.com/invite/9k2VdPn2FR"&gt;Discord channel&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;This post was originally published on &lt;a href="https://stepzen.com/blog/getting-started-with-graphql-in-angular"&gt;stepzen.com&lt;/a&gt;. Reposted automatically with &lt;a href="https://reposted.io?utm_source=postFooter"&gt;Reposted.io&lt;/a&gt;. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a JWT Login Flow with Auth0, Next.js, and StepZen</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Wed, 15 Feb 2023 13:34:42 +0000</pubDate>
      <link>https://forem.com/stepzen/building-a-jwt-login-flow-with-auth0-nextjs-and-stepzen-2j62</link>
      <guid>https://forem.com/stepzen/building-a-jwt-login-flow-with-auth0-nextjs-and-stepzen-2j62</guid>
      <description>&lt;p&gt;Almost every frontend application needs some form of authentication. This post will build a JWT login flow with Auth0, Next.js, and StepZen. Auth0 Next.js authentication library &lt;code&gt;nextjs-auth0&lt;/code&gt;, a library maintained by Auth0 to make integrating with Next.js flawless, will handle the authentication flow. Auth0 is a popular authentication provider that supports many different authentication methods, including social login, passwordless login, and more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TLDR; You can find the complete source code for this blog post on &lt;a href="https://github.com/stepzen-dev/examples/tree/main/with-auth0/authorization-jwt"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What does the login flow look like?
&lt;/h2&gt;

&lt;p&gt;For this login flow, we will rely on OAuth 2.0 and more specifically the &lt;a href="https://stepzen.com/blog/authenticating-graphql-apis-with-oauth2"&gt;Authorization Code Grant flow&lt;/a&gt;. This flow involves both a frontend and a backend. The frontend application will handle the login flow and redirect the user to the backend. The backend will exchange the authorization code for a JSON Web Token (JWT) and return it to the frontend application. The frontend application will then use the JWT to make requests to the backend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UXWPmqKU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/validating-jwt-tokens/flow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UXWPmqKU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/validating-jwt-tokens/flow.png" alt="Authorization Code Grant flow with Auth0 and StepZen" width="582" height="610"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The frontend application will be a Next.js application that uses the &lt;code&gt;nextjs-auth0&lt;/code&gt; library to handle the login flow. In this application, users click a button that brings them to the Auth0 Universal Login page. From this page, they can log in using a combination of email address and password, or one of the many social providers that are available in Auth0. After logging in, the user is asked to grant access to their profile information to the authorization server. The backend StepZen GraphQL API references an &lt;a href="https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets"&gt;Auth0 JSON Web Key Set&lt;/a&gt; to verify the JWT before returning sensitive data to the frontend application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Auth0
&lt;/h2&gt;

&lt;p&gt;​In this section, we will configure our Auth0 account to integrate it into our application later. This involves creating an Auth0 account, creating an API in the Auth0 dashboard, and an application that will be used to generate access tokens for our StepZen GraphQL API.&lt;/p&gt;

&lt;p&gt;First, you need to have an Auth0 account. If you don't have one yet, you can create one for free by following the instructions on the &lt;a href="https://auth0.com/"&gt;Auth0 website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Second, we need to create an API in Auth0. This API will represent our StepZen GraphQL API and give it access to the Auth0 authorization server. To do this, we need to go to the Auth0 dashboard and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Click the &lt;strong&gt;Applications&lt;/strong&gt; link in the left navigation pane.&lt;/li&gt;
&lt;li&gt;  Click the &lt;strong&gt;APIs`&lt;/strong&gt; link in the left navigation pane.&lt;/li&gt;
&lt;li&gt;  Click the &lt;strong&gt;+ Create API&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;  On this page you need to fill out the following fields:​

&lt;ul&gt;
&lt;li&gt;  Enter a name in the &lt;em&gt;Name&lt;/em&gt; field to help you identify this client. For example: "My StepZen API".&lt;/li&gt;
&lt;li&gt;  For the &lt;em&gt;Identifier&lt;/em&gt; field, enter a unique value. For example: "&lt;a href="https://my-stepzen-api.com"&gt;https://my-stepzen-api.com&lt;/a&gt;".&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;  And click the &lt;strong&gt;Create&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g9eWKWfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-auth0-login-setup-api.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g9eWKWfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-auth0-login-setup-api.png" alt="Create an API in Auth0" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should now see a page that contains the Identifier and Audience fields. The &lt;code&gt;Identifier&lt;/code&gt; is the URL that will be used to identify your API; this is the value that will be used to identify your API when requesting an access token. We will need these values later on, so copy them somewhere.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not setting up an API in this stage will lead to Auth0 creating an &lt;em&gt;opaque&lt;/em&gt; access token. This token will not be able to be validated by StepZen, but only by Auth0. This is not what we want, so make sure to create an API.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, we need to create an application in Auth0. This application is the authorization server that will be used to generate access tokens for our StepZen GraphQL API.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Go Back to the &lt;strong&gt;Applications&lt;/strong&gt; page.&lt;/li&gt;
&lt;li&gt;  Click the &lt;strong&gt;+ Create Application&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;  Fill out the following fields:​

&lt;ul&gt;
&lt;li&gt;  Enter a name in the &lt;em&gt;Name&lt;/em&gt; field to help you identify this client. For example: "My StepZen App".&lt;/li&gt;
&lt;li&gt;  For application type, select &lt;em&gt;Single Page Web Applications&lt;/em&gt; (or &lt;em&gt;Regular Web Applications&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;  Click the &lt;strong&gt;Create&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go the &lt;strong&gt;Settings&lt;/strong&gt; tab to find the configuration needed to integrate with StepZen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Domain​&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Client ID​&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Client Secret​&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Oviyk-d4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-auth0-login-setup-application.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Oviyk-d4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-auth0-login-setup-application.png" alt="Create an Application in Auth0" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the values for the &lt;em&gt;Domain&lt;/em&gt;, &lt;em&gt;Client ID&lt;/em&gt;, and &lt;em&gt;Client Secret&lt;/em&gt; fields. We will need these values in our frontend application later on.&lt;/p&gt;

&lt;p&gt;We also need to configure the application to allow it to redirect to our frontend application. Scroll down to the &lt;strong&gt;Allowed Callback URLs&lt;/strong&gt; field and add the following URL: "&lt;a href="http://localhost:3000/api/auth/callback"&gt;http://localhost:3000/api/auth/callback&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SSgQM7Wc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-auth0-login-setup-application-callback.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SSgQM7Wc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-auth0-login-setup-application-callback.png" alt="Create the allowed callbacks in Auth0" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! We have now configured our Auth0 account and can move on to the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Next.js application
&lt;/h2&gt;

&lt;p&gt;In this section, we will create a Nextjs frontend application to handle the login flow with &lt;code&gt;nextjs-auth0&lt;/code&gt;. This application will use the &lt;code&gt;nextjs-auth0&lt;/code&gt; library to handle the login flow. This library will take the redirect to the Auth0 Universal Login page and handle the callback from the Auth0 authorization server. It will also handle storing the JWT in the browser and, optionally, refreshing the JWT when it expires.&lt;/p&gt;

&lt;p&gt;You can create a new Nextjs application by running the following command:​&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
&lt;/code&gt;npx create-next-app`&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The Next.js setup will prompt you with a few questions, such as the name you want to give to the application, if you want to use TypeScript, and if you want to use experimental features. We will use the default settings for this post, so you can press enter to accept the default values.&lt;/p&gt;

&lt;p&gt;Once you've finished the setup of the Next.js application, let's install the following dependency that is needed for authentication:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
npm install @auth0/nextjs-auth0&lt;/p&gt;

&lt;h1&gt;
  
  
  or if you're using yarn
&lt;/h1&gt;

&lt;p&gt;yarn add @auth0/nextjs-auth0&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And add your Auth0 API and Application configuration to the &lt;code&gt;.env&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
AUTH0_SECRET='LONG_RANDOM_VALUE' # A long, secret value used to encrypt the session cookie&lt;br&gt;
AUTH0_BASE_URL='http://localhost:3000'&lt;br&gt;
AUTH0_ISSUER_BASE_URL='https://YOUR_AUTH0_DOMAIN.auth0.com'&lt;br&gt;
AUTH0_CLIENT_ID='YOUR_AUTH0_CLIENT_ID'&lt;br&gt;
AUTH0_CLIENT_SECRET='YOUR_AUTH0_CLIENT_ID'&lt;br&gt;
AUTH0_AUDIENCE='YOUR_AUTH0_API_IDENTIFIER'&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can execute the following command to generate a suitable string for the &lt;code&gt;AUTH0_SECRET&lt;/code&gt; value: &lt;code&gt;node -e "console.log(crypto.randomBytes(32).toString('hex'))"&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the configuration in place, we can now add the code to the Next.js application to use the &lt;code&gt;nextjs-auth0&lt;/code&gt; library to handle the login flow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a new file called &lt;code&gt;pages/api/auth/[...auth0].ts&lt;/code&gt; (or create the file as &lt;code&gt;.js&lt;/code&gt; if you prefer not to use TypeScript). The &lt;code&gt;nextjs-auth0&lt;/code&gt; library will use this file to handle the login flow and as the callback URL for the Auth0 authorization server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following code to the new &lt;code&gt;pages/api/auth/[...auth0].ts&lt;/code&gt; file:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`ts&lt;br&gt;
import { handleAuth, handleLogin } from '@auth0/nextjs-auth0';&lt;/p&gt;

&lt;p&gt;export default handleAuth({&lt;br&gt;
  login: handleLogin({&lt;br&gt;
    authorizationParams: {&lt;br&gt;
      audience: process.env.AUTH0_AUDIENCE, // or AUTH0_IDENTIFIER&lt;br&gt;
      // Add the &lt;code&gt;offline_access&lt;/code&gt; scope to also get a Refresh Token&lt;br&gt;
      scope: 'openid profile email', // or AUTH0_SCOPE&lt;br&gt;
    },&lt;br&gt;
  }),&lt;br&gt;
});&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We also need to wrap the application with the &lt;code&gt;UserProvider&lt;/code&gt; component. This component will be used to store the user information in the React context. This will allow us to access the user information in any component in the application. For example, by using any of the Hooks provided by &lt;code&gt;nextjs-auth0&lt;/code&gt;. To do this, we need to add the following code to the &lt;code&gt;pages/_app.tsx&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`ts&lt;br&gt;
// pages/_app.tsx&lt;br&gt;
import '@/styles/globals.css';&lt;br&gt;
import type { AppProps } from 'next/app';&lt;br&gt;
import { UserProvider } from '@auth0/nextjs-auth0/client';&lt;/p&gt;

&lt;p&gt;export default function App({ Component, pageProps }: AppProps) {&lt;br&gt;
  return (&lt;br&gt;
    &lt;br&gt;
      &lt;br&gt;
    &lt;br&gt;
  );&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The last step is to add a login button to the application. To do this, we need to add the replace the contents in the &lt;code&gt;pages/index.tsx&lt;/code&gt; file with the following code:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`tsx&lt;br&gt;
// pages/index.tsx&lt;br&gt;
import Head from 'next/head';&lt;br&gt;
import Link from 'next/link';&lt;br&gt;
import styles from '@/styles/Home.module.css';&lt;/p&gt;

&lt;p&gt;export default function Home() {&lt;br&gt;
  return (&lt;br&gt;
    &amp;lt;&amp;gt;&lt;br&gt;
      &lt;/p&gt;
&lt;br&gt;
        My StepZen App&lt;br&gt;
        &lt;br&gt;
        &lt;br&gt;
        &lt;br&gt;
      
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;main className={styles.main}&amp;gt;
    &amp;lt;Link href='/api/auth/login' className={styles.loginButton}&amp;gt;
      &amp;lt;span className={styles.auth0Logo} /&amp;gt;Login with Auth0
    &amp;lt;/Link&amp;gt;
  &amp;lt;/main&amp;gt;
&amp;lt;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;);&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  And finally, we need to add some styles to the application. Open the file called &lt;code&gt;styles/Home.module.css&lt;/code&gt; and add the following code to the bottom of it:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`css&lt;br&gt;
.loginButton {&lt;br&gt;
  display: flex;&lt;br&gt;
  align-items: center;&lt;br&gt;
  background: #eb5424;&lt;br&gt;
  padding: 10px 20px;&lt;br&gt;
  border-radius: 10px;&lt;br&gt;
  font-size: larger;&lt;br&gt;
  color: white;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;.auth0Logo {&lt;br&gt;
  width: 32px;&lt;br&gt;
  height: 32px;&lt;br&gt;
  margin-right: 10px;&lt;br&gt;
  background: url('/auth0_icon.svg');&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Now run the application by executing the following command:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
npm run dev&lt;/p&gt;

&lt;h1&gt;
  
  
  or if you're using yarn
&lt;/h1&gt;

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

&lt;ul&gt;
&lt;li&gt;  Open the application in your browser by navigating to &lt;code&gt;http://localhost:3000&lt;/code&gt;. You should see a login button:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OPJk1BSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-login-flow-auth0-login-button.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OPJk1BSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-login-flow-auth0-login-button.png" alt="Login button for Auth0 in a Next.js app" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Once you press the login button, you should be redirected to the Auth0 Universal Login page. Sign up here for a new account that will be added to the linked Auth0 account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dkxxUJtb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-login-flow-auth0-login-screen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dkxxUJtb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-login-flow-auth0-login-screen.png" alt="Auth0 Universal Login page" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  After clicking the &lt;strong&gt;Continue&lt;/strong&gt; button, you should be redirected back to the application. If you open the browser's developer tools and look at the cookies, you should see a new cookie added that includes your JWT. This cookie is used to authenticate you in the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We now have the first part of the login flow that uses Auth0 to get a JWT. Next, we want to use this JWT to authenticate the user in the StepZen GraphQL API, so we can fetch the user's profile information from the Auth0 API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a StepZen GraphQL API
&lt;/h2&gt;

&lt;p&gt;With StepZen, you can create a GraphQL API for every data source, including REST APIs, databases, and more. In this section, we will create a GraphQL API that uses the Auth0 JWT to authenticate the user. The GraphQL API will fetch the user's profile information from the Auth0 API.&lt;/p&gt;

&lt;p&gt;First, we need to create a new StepZen project. To do this, create a new directory called &lt;code&gt;stepzen&lt;/code&gt; in the root of your project and run the following command in your terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
&lt;/code&gt;stepzen init api/jwt-login-flow`&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will create a new StepZen configuration file and set the endpoint name to &lt;code&gt;api/jwt-login-flow&lt;/code&gt;. You can also choose to use a different name if you prefer.&lt;/p&gt;

&lt;p&gt;To set up the StepZen GraphQL API, we need to complete the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create a new schema file called &lt;code&gt;api.graphql&lt;/code&gt;. This file will contain the GraphQL schema for the API, including a query to get user information from the Auth0 API. Replace the value for &lt;code&gt;YOUR_AUTH0_DOMAIN&lt;/code&gt; with the domain of your Auth0 account:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`graphql&lt;br&gt;
type User {&lt;br&gt;
  email: String&lt;br&gt;
  email_verified: Boolean&lt;br&gt;
  name: String&lt;br&gt;
  nickname: String&lt;br&gt;
  picture: String&lt;br&gt;
  sub: String&lt;br&gt;
  updated_at: DateTime&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;type Query {&lt;br&gt;
  me: User&lt;br&gt;
    @rest(&lt;br&gt;
      endpoint: "&lt;a href="https://YOUR_AUTH0_DOMAIN/userinfo"&gt;https://YOUR_AUTH0_DOMAIN/userinfo&lt;/a&gt;"&lt;br&gt;
      forwardheaders: ["Authorization"]&lt;br&gt;
    )&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  StepZen needs to have an &lt;code&gt;index.graphql&lt;/code&gt; that references the &lt;code&gt;api.graphql&lt;/code&gt; file. Create a new file called &lt;code&gt;index.graphql&lt;/code&gt; and add the following code to it:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;graphql&lt;br&gt;
schema @sdl(files: ["api.graphql"]) {&lt;br&gt;
  query: Query&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  To verify the Auth0 JWT, we need to create a new file called &lt;code&gt;config.yaml&lt;/code&gt;. In this file, we'll add the configuration to valide the JWT using the JSON Web Key Set (JWKS) endpoint from Auth0 and the configuration to protect the GraphQL query &lt;code&gt;me&lt;/code&gt; so authenticated users can only access it. Replace the value for &lt;code&gt;YOUR_AUTH0_DOMAIN&lt;/code&gt; with the domain of your Auth0 account:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`yaml&lt;/p&gt;

&lt;h1&gt;
  
  
  Add the JWKS endpoint
&lt;/h1&gt;

&lt;p&gt;deployment:&lt;br&gt;
  identity:&lt;br&gt;
    jwksendpoint: '&lt;a href="https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json"&gt;https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json&lt;/a&gt;'&lt;/p&gt;

&lt;h1&gt;
  
  
  Set the policies
&lt;/h1&gt;

&lt;p&gt;access:&lt;br&gt;
  policies:&lt;br&gt;
    - type: Query&lt;br&gt;
      policyDefault:&lt;br&gt;
        condition: true&lt;br&gt;
      rules:&lt;br&gt;
        - condition: '?$jwt' # Require JWT&lt;br&gt;
          fields: [me] # Define fields that require JWT&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Now run the following command to deploy and run your StepZen project:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
&lt;/code&gt;stepzen start`&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In your terminal, you should see a message that includes the URL of your GraphQL API. Copy the URL (which starts with &lt;code&gt;https://YOUR_USERNAME.stepzen.net/api/******&lt;/code&gt; and paste it into the &lt;code&gt;.env&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;/p&gt;

&lt;h1&gt;
  
  
  Your StepZen endpoint
&lt;/h1&gt;

&lt;p&gt;STEPZEN_ENDPOINT='YOUR_STEPZEN_ENDPOINT'&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's it! We now have a working GraphQL API that can be used to validate the Auth0 JWT and fetch user information from the Auth0 API.&lt;/p&gt;

&lt;p&gt;In the next section, we'll use this GraphQL API to fetch the user's profile information in the Next.js application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching user information in the Next.js application
&lt;/h2&gt;

&lt;p&gt;In this section, we will use the GraphQL API that we created in the previous section to fetch the user's profile information in the Next.js application. We'll take the token from Auth0 using the library &lt;code&gt;nextjs-auth0&lt;/code&gt; to authenticate the user in the GraphQL API.&lt;/p&gt;

&lt;p&gt;To do this, we need to complete the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create a new file called &lt;code&gt;pages/api/graphql/index.ts&lt;/code&gt;. This file will be the API route to send requests to the StepZen GraphQL API. It uses the &lt;code&gt;withApiAuthRequired&lt;/code&gt; function from the &lt;code&gt;nextjs-auth0&lt;/code&gt; library, so the JWT will be available in the request, which we can extract using the &lt;code&gt;getAccessToken&lt;/code&gt; function. We're using an API route here as exectuting the data fetching server side is the recommended way to fetch data in Next.js. This JWT will then be forwarded to the GraphQL API together with the GraphQL query. You can add the following code to this file:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`ts&lt;br&gt;
import type { NextApiRequest, NextApiResponse } from 'next';&lt;br&gt;
import { withApiAuthRequired, getAccessToken } from '@auth0/nextjs-auth0';&lt;/p&gt;

&lt;p&gt;export default withApiAuthRequired(async function handler(&lt;br&gt;
  req: NextApiRequest,&lt;br&gt;
  res: NextApiResponse,&lt;br&gt;
) {&lt;br&gt;
  const { accessToken } = await getAccessToken(req, res);&lt;/p&gt;

&lt;p&gt;const headers = {&lt;br&gt;
    Authorization: &lt;code&gt;Bearer ${accessToken}&lt;/code&gt;,&lt;br&gt;
    'Content-Type': 'application/json',&lt;br&gt;
  };&lt;/p&gt;

&lt;p&gt;const body = req.body;&lt;/p&gt;

&lt;p&gt;try {&lt;br&gt;
    const response = await fetch(process.env?.STEPZEN_ENDPOINT || '', {&lt;br&gt;
      method: 'POST',&lt;br&gt;
      headers,&lt;br&gt;
      body,&lt;br&gt;
    });&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const json = await response.json();

res.status(200).json(json);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;} catch (e: unknown) {&lt;br&gt;
    const message = (e as Error).message;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;res.status(500).json({ error: message });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
});&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can also generate a code snippet to connect to a StepZen GraphQL API from the &lt;a href="https://dashboard.stepzen.com/"&gt;StepZen dashboard&lt;/a&gt;. You can find this under the &lt;strong&gt;Explorer&lt;/strong&gt; tab in the left pane of the dashboard by clicking on the &lt;strong&gt;Connect&lt;/strong&gt; button in the top navigation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;  In the &lt;code&gt;pages/index.tsx&lt;/code&gt; file, we're using the new API route to fetch the user's profile information. When sending a request to this API route, we need to pass along the GraphQL query to get the user's name and picture. You can add the following code to this file:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`tsx&lt;br&gt;
export default function Home() {&lt;br&gt;
  const [userData, setUserData] = useState
    name: string;&lt;br&gt;
    picture: string;&lt;br&gt;
  }&amp;gt;(null);&lt;/p&gt;

&lt;p&gt;useEffect(() =&amp;gt; {&lt;br&gt;
    async function fetchData() {&lt;br&gt;
      const res = await fetch('/api/graphql', {&lt;br&gt;
        method: 'POST',&lt;br&gt;
        body: JSON.stringify({&lt;br&gt;
          query: &lt;code&gt;&lt;br&gt;
            query {&lt;br&gt;
              me {&lt;br&gt;
                name&lt;br&gt;
                picture&lt;br&gt;
              }&lt;br&gt;
            }&lt;br&gt;
&lt;/code&gt;,&lt;br&gt;
        }),&lt;br&gt;
      });&lt;br&gt;
      const json = await res.json();&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  if (json?.data?.me) setUserData(json.data.me);
}

fetchData();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}, [setUserData]);&lt;/p&gt;

&lt;p&gt;return (&lt;br&gt;
    // ...&lt;br&gt;
  );&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  After retrieving the user's profile information, we can display it in the UI. You can add the following code to the &lt;code&gt;pages/index.tsx&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;tsx&lt;br&gt;
return (&lt;br&gt;
  &amp;lt;main className={styles.main}&amp;gt;&lt;br&gt;
    &amp;lt;div className={styles.center}&amp;gt;&lt;br&gt;
      {userData ? (&lt;br&gt;
        &amp;lt;div className={styles.profile}&amp;gt;&lt;br&gt;
          &amp;lt;img&lt;br&gt;
            src={userData.picture}&lt;br&gt;
            alt={&lt;/code&gt;${userData.name}'s profile picture&lt;code&gt;}&lt;br&gt;
            width={200}&lt;br&gt;
            height={200}&lt;br&gt;
          /&amp;gt;&lt;br&gt;
          &amp;lt;p&amp;gt;&lt;br&gt;
            &amp;lt;strong&amp;gt;Welcome {userData?.name}!&amp;lt;/strong&amp;gt;{' '}&lt;br&gt;
            &amp;lt;a href='/api/auth/logout'&amp;gt;Logout&amp;lt;/a&amp;gt;&lt;br&gt;
          &amp;lt;/p&amp;gt;&lt;br&gt;
        &amp;lt;/div&amp;gt;&lt;br&gt;
      ) : (&lt;br&gt;
        &amp;lt;Link href='/api/auth/login' className={styles.loginButton}&amp;gt;&lt;br&gt;
          &amp;lt;span className={styles.auth0Logo} /&amp;gt;&lt;br&gt;
          Login with Auth0&lt;br&gt;
        &amp;lt;/Link&amp;gt;&lt;br&gt;
      )}&lt;br&gt;
    &amp;lt;/div&amp;gt;&lt;br&gt;
  &amp;lt;/main&amp;gt;&lt;br&gt;
)&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next.js recommends using the &lt;code&gt;Image&lt;/code&gt; component from &lt;code&gt;next/image&lt;/code&gt; to render images. However, when rendering remote sources, you need to allow access to the remote URLs of these sources. Therefore, we're using the &lt;code&gt;img&lt;/code&gt; tag instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;  Finally, we need to add the styling for the profile information. You can add the following code to the &lt;code&gt;Home.module.css&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`css&lt;br&gt;
.profile {&lt;br&gt;
  display: flex;&lt;br&gt;
  justify-content: center;&lt;br&gt;
  align-items: center;&lt;br&gt;
  flex-direction: column;&lt;br&gt;
  margin-top: 20px;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;.profile img {&lt;br&gt;
  border-radius: 50%;&lt;br&gt;
  margin-bottom: 20px;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;.profile a {&lt;br&gt;
  color: #eb5424;&lt;br&gt;
  text-decoration: underline;&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Now, if you open the application in the browser again and click on the &lt;strong&gt;Login with Auth0&lt;/strong&gt; button, you should be redirected to the Auth0 login page. After logging in, you should see the user's profile information in the UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vs76VaCH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-login-flow-auth0-login-profile-page.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vs76VaCH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/jwt-login-flow-auth0-login-profile-page.png" alt="Application after logging in" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  As a finishing touch, we can show a loading indicator while the application checks if the user is authenticated and fetches the user's profile information. Therefore the &lt;code&gt;useUser&lt;/code&gt; hook should be imported from &lt;code&gt;@auth0/nextjs-auth0/client&lt;/code&gt; and the &lt;code&gt;isLoading&lt;/code&gt; property should be used to check if the user is authenticated. You can add the following code to the &lt;code&gt;pages/index.tsx&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`tsx&lt;br&gt;
import { useEffect, useState } from 'react';&lt;br&gt;
import Head from 'next/head';&lt;br&gt;
import Link from 'next/link';&lt;br&gt;
import { useUser } from '@auth0/nextjs-auth0/client';&lt;br&gt;
import styles from '@/styles/Home.module.css';&lt;/p&gt;

&lt;p&gt;export default function Home() {&lt;br&gt;
  const { isLoading } = useUser();&lt;/p&gt;

&lt;p&gt;// ...&lt;/p&gt;

&lt;p&gt;return (&lt;br&gt;
    &lt;br&gt;
      {isLoading ? (&lt;br&gt;
        Loading...&lt;br&gt;
      ) : (&lt;br&gt;
        &lt;br&gt;
        {&lt;br&gt;
          // ...&lt;br&gt;
        } &lt;br&gt;
        &lt;br&gt;
      )}&lt;br&gt;
      &lt;br&gt;
  );&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Great! With this, we've implemented the login flow using Auth0 and StepZen. You can find the complete source code for this blog post on &lt;a href="https://github.com/stepzen-dev/examples/tree/main/with-auth0/authorization-jwt"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps?
&lt;/h2&gt;

&lt;p&gt;The flow we've implemented in this blog post is a typical pattern for frontend applications that want to provide a secure way to authenticate users. The application uses the &lt;code&gt;@auth0/nextjs-auth0&lt;/code&gt; package to handle the authentication flow and a StepZen GraphQL API to verify the JWT on the server side. This way, the application can use the user's profile information on both the client side and in requests to the GraphQL API.&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://twitter.com/stepzen_dev"&gt;Twitter&lt;/a&gt; or &lt;a href="https://discord.gg/9k2VdPn2FR"&gt;join our Discord community&lt;/a&gt; to stay updated about our latest developments.&lt;/p&gt;




&lt;p&gt;This post was originally published on &lt;a href="https://stepzen.com/blog/building-jwt-login-flow-auth0-nextjs-stepzen"&gt;stepzen.com&lt;/a&gt;. Reposted automatically with &lt;a href="https://reposted.io?utm_source=postFooter"&gt;Reposted.io&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Comparing GraphQL Directives: Type System Vs. Executable Directive Locations</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Wed, 01 Feb 2023 16:12:17 +0000</pubDate>
      <link>https://forem.com/stepzen/comparing-graphql-directives-type-system-vs-executable-directive-locations-2ab1</link>
      <guid>https://forem.com/stepzen/comparing-graphql-directives-type-system-vs-executable-directive-locations-2ab1</guid>
      <description>&lt;p&gt;Have you ever wondered why some directives have to be added to your GraphQL schemas while others you can only use in runtime? That's because there are two types of directive locations: type system directive locations and executable directive locations.&lt;/p&gt;

&lt;p&gt;Earlier, we wrote about the &lt;a href="https://stepzen.com/blog/graphql-directives" rel="noopener noreferrer"&gt;different directives&lt;/a&gt; there are in GraphQL. This post will recapture what directives are and examine the difference between the different locations directives can be applied to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remind me, what is a GraphQL Directive?
&lt;/h2&gt;

&lt;p&gt;Directives in GraphQL offer a means to change runtime execution and type validation in a GraphQL document. You can apply directives to many different locations in a GraphQL document, such as fields, fragments, and operations. They allow you to modify the behavior of GraphQL's execution by providing options that are not available through field arguments. For instance, you can conditionally include or exclude a field using directives, as you'll learn in this post.&lt;/p&gt;

&lt;p&gt;You can use built-in or custom directives when building or consuming a GraphQL API. Built-in directives are defined by the GraphQL specification, while custom directives are defined by the GraphQL service or tool you use. Let's look at some of the built-in directives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Built-in Directives
&lt;/h3&gt;

&lt;p&gt;The GraphQL specification defines a set of built-in directives. Directives have a specific name and can accept values of any input type as arguments. They can be applied to, for example, types, fields, fragments, and operations.&lt;/p&gt;

&lt;p&gt;The following list has all the built-in directives that are defined by the GraphQL specification:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;@skip&lt;/code&gt;: This directive can be used to exclude fields from a query operation conditionally.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;@include&lt;/code&gt;: Does the opposite of &lt;code&gt;@skip&lt;/code&gt; and can be used to include fields in a query operation conditionally.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;@deprecated&lt;/code&gt;: This directive can mark a field or an enum value as deprecated and can provide a reason for deprecation to the client.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;@specifiedBy&lt;/code&gt;: This directive can be used to provide a URL for the specification of a custom scalar.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: As GraphQL evolves, new execution capabilities may be introduced and exposed through directives. The directives &lt;code&gt;@defer&lt;/code&gt; and &lt;code&gt;@stream&lt;/code&gt; have been announced by the GraphQL Working Group but aren't listed in the latest draft of the GraphQL specification.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;GraphQL services and tools can also provide custom directives beyond those already mentioned. We'll learn more about custom directives in the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Directives
&lt;/h3&gt;

&lt;p&gt;Custom directives can be used to extend the functionality of GraphQL and are the preferred way to add custom behavior to a GraphQL API. Different GraphQL server and client implementations are already using custom directives to add additional functionality to GraphQL.&lt;/p&gt;

&lt;p&gt;For example, at StepZen, we have defined custom directives to connect with your data sources, such as the &lt;code&gt;@rest&lt;/code&gt;, &lt;code&gt;@dbquery&lt;/code&gt;, and &lt;code&gt;@graphql&lt;/code&gt; directives. When using StepZen to develop your GraphQL API, you can use these directives to connect to REST APIs, databases, and other GraphQL APIs. Additionally, we have defined the &lt;code&gt;@materializer&lt;/code&gt; and &lt;code&gt;@sequence&lt;/code&gt; directives to mix and match data from multiple data sources in a single type.&lt;/p&gt;

&lt;p&gt;But next to built-in and custom directives, there is another distinction to be made between directives: the location they are used in. In the next section, we'll examine the difference between directives applied to type system and executable locations in GraphQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type System Directive Locations vs. Executable Directive Locations
&lt;/h2&gt;

&lt;p&gt;Directives in GraphQL can be applied to different locations, where the GraphQL Specification makes a distinction between type system directive locations and executable directive locations. Directives applied to either of these locations have the same syntax; therefore, their location determines how a GraphQL implementation handles them. However, a directive may support both type system and executable locations, though typically, a single directive supports only one location. For example, &lt;code&gt;@skip&lt;/code&gt; only supports executable directive locations.&lt;/p&gt;

&lt;p&gt;Let's look at the locations where directives can be applied and see examples for both types.&lt;/p&gt;

&lt;h3&gt;
  
  
  Directives that apply to the type system
&lt;/h3&gt;

&lt;p&gt;Directives that apply to the type system are used to annotate a schema, object type, or field definition written in GraphQL SDL (schema definition language) when building a GraphQL server. Both built-in and custom directives can be used in type system directive locations, and GraphQL server implementations can then use these annotations to take additional actions. Therefore, type system directive locations are also called "schema directives" as they only exist on the GraphQL schema itself.&lt;/p&gt;

&lt;p&gt;The following locations in a GraphQL schema are valid type system directive locations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;SCHEMA&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;SCALAR&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;OBJECT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;FIELD_DEFINITION&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;ARGUMENT_DEFINITION&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;INTERFACE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;UNION&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;ENUM&lt;/code&gt; &amp;amp; &lt;code&gt;ENUM_VALUE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;INPUT_OBJECT&lt;/code&gt; &amp;amp; &lt;code&gt;INPUT_FIELD_DEFINITION&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples of directives that apply to the type system include &lt;code&gt;@deprecated&lt;/code&gt;, a built-in directive that can mark a field as deprecated. Let's see what it looks like in a schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;deprecated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instead&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the &lt;code&gt;@deprecated&lt;/code&gt; directive marks the &lt;code&gt;name&lt;/code&gt; field as deprecated. The &lt;code&gt;reason&lt;/code&gt; argument provides a reason for deprecation available to services that introspect the schema. The client could then, for example, warn the user that the field &lt;code&gt;name&lt;/code&gt; is deprecated and shouldn't be used anymore.&lt;/p&gt;

&lt;p&gt;When you would look up the &lt;code&gt;User&lt;/code&gt; type in the documentation generated by GraphiQL, you should see warnings about using the field &lt;code&gt;name&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo05zaqyq3hgdaf0eufom.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo05zaqyq3hgdaf0eufom.png" alt="Deprecated field in GraphiQL" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another example of a directive that can be applied to the type system is &lt;code&gt;@rest&lt;/code&gt;, a custom directive only available in StepZen GraphQL implementations. The data for the &lt;code&gt;User&lt;/code&gt; type in the example above is fetched from a REST API using the &lt;code&gt;@rest&lt;/code&gt; directive, which is defined in the following way on a query field in a GraphQL schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="n"&gt;jsonplaceholder&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typicode&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run an operation that includes the &lt;code&gt;user&lt;/code&gt; field, the StepZen GraphQL API fetches the data from the REST API and returns it to the client. The &lt;code&gt;@rest&lt;/code&gt; directive is applied to a type system location because it annotates the &lt;code&gt;user&lt;/code&gt; field in the schema. It lets you declaratively define how the data for the &lt;code&gt;user&lt;/code&gt; field should be fetched, rather than having to write a resolver function, as you might expect from other GraphQL server implementations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Directives that apply to execution
&lt;/h3&gt;

&lt;p&gt;You can use directives that apply to execution to modify the behavior of an operation, field, or fragment in runtime execution. For example, directives that apply to execution can include or exclude fields or perform additional data processing before the response is returned.&lt;/p&gt;

&lt;p&gt;Executable directive locations in GraphQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;QUERY&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;MUTATION&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;SUBSCRIPTION&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;FIELD&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;FRAGMENT_DEFINITION&lt;/code&gt; &amp;amp; &lt;code&gt;FRAGMENT_SPREAD&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;INLINE_FRAGMENT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;VARIABLE_DEFINITION&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similar to directives that apply to the type system directives, both built-in and custom directives can be applied to executable locations. Most built-in directives are executable, such as &lt;code&gt;@skip&lt;/code&gt; and &lt;code&gt;@include&lt;/code&gt;, which you can use to include or exclude fields in an operation conditionally.&lt;/p&gt;

&lt;p&gt;Let's see what the &lt;code&gt;@include&lt;/code&gt; directive looks like in a query operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$showName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;!)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;@include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$showName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;@include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$showName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@include&lt;/code&gt; directive conditionally includes the &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; fields in the response. The &lt;code&gt;if&lt;/code&gt; argument specifies a boolean value determining whether to include the field in the response. In the example above, the &lt;code&gt;if&lt;/code&gt; argument is set to a variable &lt;code&gt;$showName&lt;/code&gt;, which is defined in the operation variables. The variable's value can be set to &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; to include or exclude the fields in the response.&lt;/p&gt;

&lt;p&gt;When you'd pass this operation to a GraphQL API, the response should include the fields &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; in the response if the value of the variable &lt;code&gt;$showName&lt;/code&gt; is set to &lt;code&gt;true&lt;/code&gt; as you can see in the screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2cg46qnigyhsix5aivz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2cg46qnigyhsix5aivz.png" alt="Include fields with directives in GraphiQL" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another example of an executable directive is &lt;code&gt;@sort&lt;/code&gt;, a custom directive only available in StepZen GraphQL implementations.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;@sort&lt;/code&gt; directive, you can sort the data returned by a field in a GraphQL operation. You can use the &lt;code&gt;@sort&lt;/code&gt; directive on a field that returns either a list of leaf fields or a list of objects.&lt;/p&gt;

&lt;p&gt;For example, let's say you have a &lt;code&gt;products&lt;/code&gt; field that returns a list of &lt;code&gt;tags&lt;/code&gt;. You can use the &lt;code&gt;@sort&lt;/code&gt; directive to sort the tags by alphabetical order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ['c', 'b', 'a', null]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will be transformed to this when the &lt;code&gt;@sort&lt;/code&gt; directive is used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;@sort&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# [null, 'a', 'b', 'c']&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next to a list of leaf fields, the same &lt;code&gt;@sort&lt;/code&gt; directive can be applied to a field that returns a list of objects. You can find more information on using the &lt;code&gt;@sort&lt;/code&gt; directive in the &lt;a href="https://stepzen.com/docs/custom-graphql-directives/directives" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;In this blog post, you learned about built-in and custom directives and how they can be applied to different locations in GraphQL. These locations are either type system or executable locations. Directives applied to the type system directives are used in GraphQL Schema Definition Language (SDL) only. At the same time, directives applied to executable locations are used to modify the response of GraphQL in runtime execution.&lt;/p&gt;

&lt;p&gt;Want to learn more about building and consuming GraphQL APIs? Follow StepZen on &lt;a href="https://twitter.com/stepzen_dev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://discord.gg/9k2VdPn2FR" rel="noopener noreferrer"&gt;join our Discord community&lt;/a&gt; to stay updated about our latest developments.&lt;/p&gt;




&lt;p&gt;This post was originally published on &lt;a href="https://stepzen.com/blog/type-system-directives-versus-executable-directives" rel="noopener noreferrer"&gt;stepzen.com&lt;/a&gt;. Reposted automatically with &lt;a href="https://reposted.io?utm_source=postFooter" rel="noopener noreferrer"&gt;Reposted.io&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>web3</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>Authenticating GraphQL APIs with OAuth 2.0</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Wed, 25 Jan 2023 17:33:58 +0000</pubDate>
      <link>https://forem.com/stepzen/authenticating-graphql-apis-with-oauth-20-1gl9</link>
      <guid>https://forem.com/stepzen/authenticating-graphql-apis-with-oauth-20-1gl9</guid>
      <description>&lt;p&gt;There are many different ways to handle authentication in GraphQL, but one of the most common is to use OAuth 2.0 - and, more specifically, JSON Web Tokens (JWT) or Client Credentials.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll look at how to use OAuth 2.0 to authenticate GraphQL APIs using two different flows: the Authorization Code flow and the Client Credentials flow. We'll also look at how to use StepZen to manage authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is OAuth 2.0?
&lt;/h2&gt;

&lt;p&gt;But first, what is OAuth 2.0? OAuth 2.0 is an open standard for authorization that allows one application to let another application access certain parts of a user's account without giving away the user's password. There are different ways to set up this type of authorization, called "flows", and it depends on the type of application you are building.&lt;/p&gt;

&lt;p&gt;For example, if you're building a mobile app, you will use the "Authorization Code" flow. This flow will ask the user to permit the app to access their account, and then the app will receive a code to use to get an access token (JWT). The access token will allow the app to access the user's information on the website. You might have seen this flow when you log in to a website using a social media account, such as Facebook or Twitter.&lt;/p&gt;

&lt;p&gt;Another example is if you're building a server-to-server application, you will use the "Client Credentials" flow. This flow involves sending the website's unique information, like a client ID and secret, to get an access token (JWT). The access token will allow the server to access the user's information on the website. This flow is quite common for APIs that need to access a user's data, such as a CRM or a marketing automation tool.&lt;/p&gt;

&lt;p&gt;Let's have a look at these two flows in more detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization Code Flow (using JWT)
&lt;/h2&gt;

&lt;p&gt;The most common way to use OAuth 2.0 is with the Authorization Code flow, which involves using JSON Web Tokens (JWT). As mentioned above, this flow is used when you want to build a mobile or web application that needs to access a user's data from a different application.&lt;/p&gt;

&lt;p&gt;For example, if you have a GraphQL API that allows users to access their data, you can use a JWT to verify that the user is authorized to access the data. The JWT could contain information about the user, such as the user's ID, and the server can use this ID to query the database and return the user's data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhsg0bx3f33p2qgu9if3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhsg0bx3f33p2qgu9if3w.png" alt="Flow to get JWT" width="582" height="610"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You would need a frontend application that can redirect the user to the authorization server and then redirect the user back to the frontend application with the authorization code. The frontend application can then exchange the authorization code for an access token (JWT) and then use the JWT to make requests to the GraphQL API.&lt;/p&gt;

&lt;p&gt;The JWT can be sent to the GraphQL API in the &lt;code&gt;Authorization&lt;/code&gt; header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://USERNAME.stepzen.net/api/hello-world/__graphql&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="err"&gt;--header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"Authorization:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JWT_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="err"&gt;--header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"Content-Type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="err"&gt;--data-raw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the server can use the JWT to verify that the user is authorized to access the data.&lt;/p&gt;

&lt;p&gt;The JWT can also contain information about the user's permissions, such as whether they can access a specific field or mutation. This is useful if you want to restrict access to specific fields or mutations or if you want to limit the number of requests a user can make. But we'll look at this in more detail after discussing the Client Credentials flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client Credentials Flow
&lt;/h2&gt;

&lt;p&gt;The Client Credentials flow is used when you want to build a server-to-server application, like an API, that needs to access information from a different application. It also relies on JWT.&lt;/p&gt;

&lt;p&gt;As mentioned above, this flow involves sending the website's unique information, like a client ID and secret, to get an access token. The access token will allow the server to access the user's information on the website. Unlike the Authorization Code flow, the Client Credentials flow doesn't involve a (frontend) client. Instead, the authorization server will directly communicate with the server that needs to access the user's information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtsswjn5j6svs3sg06e4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtsswjn5j6svs3sg06e4.png" alt="Client Credentials Flow" width="800" height="476"&gt;&lt;/a&gt;&lt;em&gt;Image from &lt;a href="https://auth0.com/docs/flows/concepts/client-credentials" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The JWT can be sent to the GraphQL API in the &lt;code&gt;Authorization&lt;/code&gt; header, in the same way as for the Authorization Code flow.&lt;/p&gt;

&lt;p&gt;In the next section, we'll look at how to implement both the Authorization Code flow and the Client Credentials flow using StepZen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using StepZen to Manage Authentication
&lt;/h2&gt;

&lt;p&gt;By default, StepZen uses API Keys to authenticate requests. This is a developer-friendly way to authenticate requests that don't require an external authorization server. But if you want to use OAuth 2.0 to authenticate requests, you can use StepZen to manage authentication. Similar to how you can use StepZen to build a GraphQL schema for all your data in a declarative way, you can also manage authentication declaratively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement Authorization Code Flow (using JWT)
&lt;/h3&gt;

&lt;p&gt;To implement the Authorization Code flow, you must set up both a (frontend) client and an authorization server. You can use an existing authorization server, such as Auth0, or build your own.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can find a complete example of using StepZen to implement the Authorization Code flow in the &lt;a href="https://github.com/stepzen-dev/examples/tree/main/with-auth0/" rel="noopener noreferrer"&gt;StepZen GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;StepZen can validate the JWTs generated by the authorization server and send them to the GraphQL API. You only need the authorization server to validate the user's credentials to generate a JWT and StepZen to validate the JWT.&lt;/p&gt;

&lt;p&gt;Let's have another look at the flow we discussed above:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhsg0bx3f33p2qgu9if3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhsg0bx3f33p2qgu9if3w.png" alt="Flow to get JWT" width="582" height="610"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this flow diagram, you can see that the frontend application redirects the user to the authorization server (from Auth0) and then turns the user back to the frontend application with the authorization code. The frontend application can then exchange the authorization code for a JWT and then use that JWT to make requests to the GraphQL API.&lt;/p&gt;

&lt;p&gt;StepZen will validate the JWT that is sent to the GraphQL API in the &lt;code&gt;Authorization&lt;/code&gt; header by configuring the JSON Web Key Set (JWKS) endpoint in the StepZen configuration in the &lt;code&gt;config.yaml&lt;/code&gt; file in your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;identity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jwksendpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YOUR_JWKS_ENDPOINT'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JWKS endpoint is a read-only endpoint that contains the public keys to verify a JWT. The public keys can only be used to validate the tokens, as you would need the private keys to sign the tokens, which is why you need to set up an authorization server to generate the JWTs.&lt;/p&gt;

&lt;p&gt;You can then limit the fields and mutations a user can access by adding &lt;a href="https://stepzen.com/docs/access-control/access-control-rules" rel="noopener noreferrer"&gt;Access Control rules&lt;/a&gt; to the GraphQL schema. For example, you can add a rule to the &lt;code&gt;me&lt;/code&gt; query to only allow access when a valid JWT is sent to the GraphQL API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;identity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jwksendpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YOUR_JWKS_ENDPOINT'&lt;/span&gt;
&lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Query&lt;/span&gt;
      &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;?$jwt'&lt;/span&gt; &lt;span class="c1"&gt;# Require JWT&lt;/span&gt;
          &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;me&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Define fields that require JWT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This rule only allows access to the &lt;code&gt;me&lt;/code&gt; query when a valid JWT is sent to the GraphQL API. If the JWT is invalid, or if no JWT is sent, the &lt;code&gt;me&lt;/code&gt; query will return an error.&lt;/p&gt;

&lt;p&gt;Earlier, we mentioned that the JWT could contain information about the user's permissions, such as whether they can access a specific field or mutation. This is useful if you want to restrict access to specific fields or mutations or if you want to limit the number of requests a user can make.&lt;/p&gt;

&lt;p&gt;You can add a rule to the &lt;code&gt;me&lt;/code&gt; query to only allow access when a user has the &lt;code&gt;admin&lt;/code&gt; role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;identity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jwksendpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YOUR_JWKS_ENDPOINT'&lt;/span&gt;
&lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Query&lt;/span&gt;
      &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$jwt.roles:String&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;has&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"admin"'&lt;/span&gt; &lt;span class="c1"&gt;# Require JWT&lt;/span&gt;
          &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;me&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Define fields that require JWT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To learn more about implementing the Authorization Code Flow with StepZen, look at the &lt;a href="https://stepzen.com/blog/simple-abac-for-graphql" rel="noopener noreferrer"&gt;Easy Attribute-based Access Control for any GraphQL API article&lt;/a&gt; on the StepZen blog.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement Client Credentials Flow
&lt;/h3&gt;

&lt;p&gt;You will also need to set up an authorization server to implement the Client Credentials flow. But instead of redirecting the user to the authorization server, the server will directly communicate with the authorization server to get an access token (JWT).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can find a complete example for implementing the Client Credentials flow in the &lt;a href="https://github.com/stepzen-dev/examples/tree/main/with-auth0/" rel="noopener noreferrer"&gt;StepZen GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, you must set up the authorization server to generate the access token. You can use an existing authorization server, such as Auth0, or build your own.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;config.yaml&lt;/code&gt; file in your StepZen project, you can configure the authorization server to generate the access token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Add the JWKS endpoint&lt;/span&gt;
&lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;identity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jwksendpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json'&lt;/span&gt;

&lt;span class="c1"&gt;# Add the authorization server configuration&lt;/span&gt;
&lt;span class="na"&gt;configurationset&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;configuration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;auth&lt;/span&gt;
      &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_CLIENT_ID&lt;/span&gt;
      &lt;span class="na"&gt;client_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_CLIENT_SECRET&lt;/span&gt;
      &lt;span class="na"&gt;audience&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_AUDIENCE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;client_id&lt;/code&gt;, &lt;code&gt;client_secret&lt;/code&gt; and &lt;code&gt;audience&lt;/code&gt; are required parameters for the authorization server to generate the access token (JWT). The &lt;code&gt;audience&lt;/code&gt; is the API's identifier for the JWT. The &lt;code&gt;jwksendpoint&lt;/code&gt; is the same as the one we used for the Authorization Code flow.&lt;/p&gt;

&lt;p&gt;In a &lt;code&gt;.graphql&lt;/code&gt; file in your StepZen project, you can define a query to get the access token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;YOUR_AUTHORIZATION_SERVER&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="n"&gt;oauth&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;postbody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"""&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;client_id&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;client_id&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;client_secret&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;client_secret&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;audience&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;audience&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;grant_type&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;client_credentials&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;"""&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;token&lt;/code&gt; mutation will request the authorization server to get the JWT. The &lt;code&gt;postbody&lt;/code&gt; contains the parameters that are required by the authorization server to generate the access token.&lt;/p&gt;

&lt;p&gt;You can then use the JWT from the response on the &lt;code&gt;token&lt;/code&gt; mutation to request the GraphQL API, by sending the JWT in the &lt;code&gt;Authorization&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;But we can do better than that. We can use the &lt;code&gt;@sequence&lt;/code&gt; custom directive to pass the response of the &lt;code&gt;token&lt;/code&gt; mutation to the query that needs authorization. This way, we don't need to send the JWT manually in the &lt;code&gt;Authorization&lt;/code&gt; header on every request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;YOUR_API_ENDPOINT&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;Authorization&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;profile&lt;/code&gt; query will first request the &lt;code&gt;token&lt;/code&gt; query to get the JWT. Then, it will send a request to the &lt;code&gt;me&lt;/code&gt; query, passing along the JWT from the response of the &lt;code&gt;token&lt;/code&gt; query as the &lt;code&gt;access_token&lt;/code&gt; argument.&lt;/p&gt;

&lt;p&gt;As you can see, all configuration is set up in a single file, and you can use the same configuration for both the Authorization Code flow and the Client Credentials flow. Both are written declarative, and both use the same JWKS endpoint to request the authorization server to verify the tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;In this blog post, you learned about common OAuth 2.0 flows and how to implement them with StepZen. It's important to note that, as with any authentication mechanism, the details of the implementation will depend on the application's specific requirements and the security measures that need to be in place.&lt;/p&gt;

&lt;p&gt;StepZen GraphQL APIs are default protected with an API key but can be configured to use any authentication mechanism. We'd love to hear what authentication mechanisms you use with StepZen and how you use them. Ping us on &lt;a href="https://twitter.com/stepzen_dev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or join our &lt;a href="https://discord.gg/9k2VdPn2FR" rel="noopener noreferrer"&gt;Discord community&lt;/a&gt; to let us know.&lt;/p&gt;




&lt;p&gt;This post was originally published on &lt;a href="https://stepzen.com/blog/authenticating-graphql-apis-with-oauth2" rel="noopener noreferrer"&gt;stepzen.com&lt;/a&gt;. Reposted automatically with &lt;a href="https://reposted.io?utm_source=postFooter" rel="noopener noreferrer"&gt;Reposted.io&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>Compose Data from Fauna and GitHub using GraphQL and StepZen</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Wed, 16 Nov 2022 15:07:54 +0000</pubDate>
      <link>https://forem.com/stepzen/compose-data-from-fauna-and-github-using-graphql-and-stepzen-2e5c</link>
      <guid>https://forem.com/stepzen/compose-data-from-fauna-and-github-using-graphql-and-stepzen-2e5c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You can find the &lt;a href="https://github.com/stepzen-dev/examples/tree/main/with-fauna" rel="noopener noreferrer"&gt;complete code example for this blog on the StepZen GitHub page&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Data composition is getting more and more important for modern APIs. Companies no longer store data in just one database; more often, data comes from multiple sources. For example, a database or third-party APIs with all sorts of specifications. In GraphQL, the composition of data in APIs is also called federation. This post will teach you how to compose data from Fauna and GitHub using GraphQL and StepZen.&lt;/p&gt;

&lt;p&gt;To show how to compose (or federate) data, we'll be combining data from Fauna and GitHub. Fauna is a distributed &lt;a href="https://fauna.com/blog/what-is-a-document-relational-database" rel="noopener noreferrer"&gt;document-relational&lt;/a&gt; database delivered as a global API. Fauna can be queried using &lt;a href="https://docs.fauna.com/fauna/current/api/fql/" rel="noopener noreferrer"&gt;Fauna Query Language&lt;/a&gt; (FQL), and also provides a &lt;a href="https://docs.fauna.com/fauna/current/learn/quick_start/gql_quick_start" rel="noopener noreferrer"&gt;native GraphQL API&lt;/a&gt;. GitHub is a popular code hosting platform for version control and collaboration, and it also provides a GraphQL API. The API we'll build in this post will take data from a GitHub repository and enrich it with data stored in Fauna using StepZen. StepZen is a GraphQL-as-a-Service platform that allows you to compose data from multiple sources into one API declaratively. The diagram below shows how the data will be composed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-github-stepzen-architecture.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-github-stepzen-architecture.png" alt="composing data from fauna and GitHub with StepZen GraphQL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can query the GraphQL API created with StepZen from any application you connect. For example, you can use the API in a web application to display a list of repositories with their stars and forks. You can also use the API in a mobile application to show the same data.&lt;/p&gt;

&lt;p&gt;First, we'll explore the GitHub GraphQL API and see how we can query it. Then we'll set up and seed a Fauna database with data. Finally, StepZen will be used to combine the data from Fauna and GitHub and return it as a single GraphQL response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explore the GitHub GraphQL API
&lt;/h2&gt;

&lt;p&gt;In this post, we'll be building a GraphQL API that composes data from Fauna and GitHub. To get started, we'll explore the GitHub GraphQL API. The GitHub GraphQL API is a public API that you can use to query data about repositories, users, organizations, and more. The API is documented on GitHub and can be queried using GraphiQL.&lt;/p&gt;

&lt;p&gt;To get started, we'll query the API to get the names and descriptions of users' repositories. The query below will return the name and description of the repositories of the user &lt;code&gt;octocat&lt;/code&gt;. You can replace the login argument with your own GitHub username.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"octocat"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;repositories&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query will return the data as seen in the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-blog-Github_GraphiQL_explorer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-blog-Github_GraphiQL_explorer.png" alt="Github GraphiQL explorer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you're not using the Github GraphiQL explorer to query the GraphQL API, you should create a &lt;a href="https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token" rel="noopener noreferrer"&gt;personal access token&lt;/a&gt; and use it in the Authorization header of your GraphQL requests. You can create a personal access token in your &lt;a href="https://github.com/settings/tokens" rel="noopener noreferrer"&gt;Github settings&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From the Github GraphiQL explorer, you can find all the fields that you can query for the GitHub repositories. This aside, we'll set up a Fauna database next that will contain our data about the repositories. We will use the data from Fauna to enrich the data from GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up Fauna
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a Fauna account
&lt;/h3&gt;

&lt;p&gt;To get started with Fauna, you need to &lt;a href="https://dashboard.fauna.com/" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; here, for example, by signing up using your GitHub account. After you've signed up, you'll be redirected to the Fauna dashboard. From the dashboard, you can create a database by clicking on the &lt;strong&gt;+ Create Database&lt;/strong&gt; button&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2FCreate_Fauna_database.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2FCreate_Fauna_database.png" alt="Create Fauna Database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give the database a name, for example, stepzen-demo and select a region where Fauna should host the database. GraphQL APIs created on StepZen free plan are hosted in the US, so we will choose that region.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Fcreate-fauna-database-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Fcreate-fauna-database-2.png" alt="Create Fauna Database 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Fauna dashboard will show the database you created. From this page, you can also add data to the database. Fauna is a document-based database, so data is stored as collections in the database instead of tables. In the next step, we will create a collection and add some data. For this, you can use the dashboard or the tool fauna-shell.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a collection
&lt;/h3&gt;

&lt;p&gt;To create the API, we will need some data to work with, so we first need to create a collection before storing data. A collection is a container for documents, the actual data stored in Fauna.There are two ways to seed your Fauna database with the initial data, via the dashboard or your terminal using fauna-shell.&lt;/p&gt;

&lt;p&gt;Let's use the dashboard to create our first collection. From the dashboard, we can upload a GraphQL schema to create the collection and the documents. The schema is a GraphQL schema but not a GraphQL API, and uses it to create the collection and documents that will be stored in Fauna.&lt;/p&gt;

&lt;p&gt;To create a collection, click on the GraphQL tab in the left menu. You can upload a GraphQL schema on this page by clicking on the Import Schema button. The file you can upload here should be in .gql or .graphql format, so you can create a new file in your editor and copy the following schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Highlight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Repository&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;relation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Repository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;coverImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;shortDescription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;highlights&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Highlight&lt;/span&gt;&lt;span class="p"&gt;]!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;repositories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Repository&lt;/span&gt;&lt;span class="p"&gt;]!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this post, we'll build a GraphQL API that returns a list of highlighted GitHub repositories enriched with data from Fauna, such as a cover image and a short description. The schema above defines the data structure of the documents that will be stored in Fauna. The &lt;code&gt;Highlight&lt;/code&gt; collection will contain documents with a field &lt;code&gt;repository&lt;/code&gt; related to the &lt;code&gt;Repository&lt;/code&gt; collection. The Repository type defines the data structure of a repository (e.g. the enriched data) and has a link to the data from GitHub via the &lt;code&gt;owner&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; fields. Let's import some of the data from GitHub to Fauna.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add data to the collections
&lt;/h3&gt;

&lt;p&gt;After you've uploaded the schema, you can add data to the collections. To add data to the &lt;code&gt;Repository&lt;/code&gt; collection, we will use the GraphQL API that Fauna provides. To do this, click on the &lt;strong&gt;GraphQL&lt;/strong&gt; tab in the left menu and click on the &lt;strong&gt;Playground&lt;/strong&gt; button. Clicking this button will open the GraphQL playground, similar to the one from Github, where you can write queries to interact with the Fauna GraphQL API.&lt;/p&gt;

&lt;p&gt;Looking at the &lt;strong&gt;Docs&lt;/strong&gt; tab in the playground, you can see the schema you uploaded earlier. You can also see the queries and mutations that you can use to interact with the Fauna GraphQL API. Fauna has automatically generated queries and mutations based on your imported schema, for example, to get a single repository by its id or to create/update a repository. Also, the queries to get all repositories and highlights are extended with pagination fields.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-blog-playground.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-blog-playground.png" alt="Fauna GraphQL Playground"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll be using the generated mutation createRepository mutation to add the data from GitHub to Fauna. The mutation below will create a new document in the &lt;code&gt;Repository&lt;/code&gt; collection. Remember the query we ran earlier to get the &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name,&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; of the repositories of the user &lt;code&gt;octocat&lt;/code&gt;? We'll use this data to store the owner and name fields from GitHub in Fauna. The &lt;code&gt;coverImage&lt;/code&gt; and &lt;code&gt;shortDescription&lt;/code&gt; fields will remain empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"octocat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hello-world"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you've run the mutation, you can see the new document in the Repository collection. You can also see the _id field that Fauna has generated for the document. This _id field is used to identify the document in Fauna, so we'll be using this _id field to link the document in the Highlight collection to the document in the Repository collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"343960570233356362"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository field in the &lt;code&gt;Highlight&lt;/code&gt; collection relates to the &lt;code&gt;Repository&lt;/code&gt; collection, meaning you could query this relationship using the Fauna GraphQL API.&lt;/p&gt;

&lt;p&gt;As we now have two GraphQL APIs, let's continue to the final part of this post and combine them into one GraphQL API using StepZen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use StepZen to GraphQL APIs
&lt;/h2&gt;

&lt;p&gt;Combining the two GraphQL APIs into one GraphQL API is done using StepZen. StepZen is a GraphQL API service that allows you to create GraphQL APIs for your data sources (SQL, NoSQL, REST, and GraphQL) or to combine multiple GraphQL APIs into one GraphQL API. StepZen can be used via a CLI and has a generous free plan.&lt;/p&gt;

&lt;p&gt;The act of combining or composing GraphQL APIs is also called federation. StepZen can also be used as a GraphQL federation service, which means combining multiple GraphQL APIs into one GraphQL API. The GraphQL APIs that are combined into one GraphQL API is called subgraphs, and for this section, we'll be using the GitHub GraphQL API and Fauna as a subgraph.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up StepZen
&lt;/h3&gt;

&lt;p&gt;To use StepZen, you should &lt;a href="https://www.npmjs.com/package/stepzen" rel="noopener noreferrer"&gt;download and install the CLI&lt;/a&gt; from npm, by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; stepzen&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing, you can choose to run StepZen locally using Docker or in the cloud by signing up for a free account at &lt;a href="https://stepzen.com/" rel="noopener noreferrer"&gt;stepzen.com&lt;/a&gt;. For this example, we'll be using the cloud version, for which you can sign up for a free account using your GitHub account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Import the GitHub GraphQL API
&lt;/h3&gt;

&lt;p&gt;Inside a new project, we'll be using the CLI first to import the Github GraphQL using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="s"&gt;stepzen import graphql`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And answer the prompts with the values below, where the prefix &lt;code&gt;github&lt;/code&gt; is added to all types and operations. Using prefixes will prevent naming conflicts once we import Fauna as a subgraph.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;? What is the GraphQL endpoint URL?
https://api.github.com/graphql

? Prefix to add to all generated &lt;span class="nb"&gt;type &lt;/span&gt;names &lt;span class="o"&gt;(&lt;/span&gt;leave blank &lt;span class="k"&gt;for &lt;/span&gt;none&lt;span class="o"&gt;)&lt;/span&gt;
github_

? Should &lt;span class="nb"&gt;type &lt;/span&gt;prefix be added to query and mutation fields as well?
Yes

? Add an HTTP header, e.g. Header-Name: header value &lt;span class="o"&gt;(&lt;/span&gt;leave blank &lt;span class="k"&gt;for &lt;/span&gt;none&lt;span class="o"&gt;)&lt;/span&gt;
Authorization: bearer ghp_&lt;span class="k"&gt;************&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To query the GraphQL API from Github, you need to pass along a &lt;a href="https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token" rel="noopener noreferrer"&gt;personal access token&lt;/a&gt; and pass it as an Authorization header to the CLI import command. You can create a personal access token in your &lt;a href="https://github.com/settings/tokens" rel="noopener noreferrer"&gt;GitHub settings&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The StepZen CLI will generate a schema containing the types and queries that are available in the GitHub GraphQL API. You can see the generated types and queries in the file &lt;code&gt;graphql/index.graphql&lt;/code&gt; in the project directory. Also, the CLI will generate a &lt;code&gt;config.yaml&lt;/code&gt; file that contains the GitHub personal access token. You can start the StepZen server by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;stepzen start&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The start command will deploy the GraphQL schemas to the StepZen cloud and start the StepZen server. The first time you run this command, you need to provide an endpoint name, &lt;code&gt;api/with-fauna&lt;/code&gt;. You can now open the GrapihQL playground from the link in the terminal to query the GitHub GraphQL API through StepZen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import the Fauna GraphQL API
&lt;/h2&gt;

&lt;p&gt;Second, we also need to import the GraphQL API for the Fauna database into StepZen. To do this, we'll be using the &lt;code&gt;stepzen import graphql&lt;/code&gt; command again, but this time we'll use the connection details to the Fauna GraphQL API.&lt;/p&gt;

&lt;p&gt;You can find the connection details in the Fauna dashboard under the "GraphQL" tab. You can copy the endpoint from the "Endpoint" field at the top and the authorization token under "HTTP headers".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-http-headers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-http-headers.png" alt="HTTP headers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And enter them in the prompts of the StepZen CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;?&lt;/span&gt; &lt;span class="s"&gt;What is the GraphQL endpoint URL?&lt;/span&gt;
&lt;span class="s"&gt;https://graphql.us.fauna.com/graphql&lt;/span&gt;

&lt;span class="pi"&gt;?&lt;/span&gt; &lt;span class="s"&gt;Prefix to add to all generated type names (leave blank for none)&lt;/span&gt;
&lt;span class="s"&gt;fauna_&lt;/span&gt;

&lt;span class="pi"&gt;?&lt;/span&gt; &lt;span class="s"&gt;Should type prefix be added to query and mutation fields as well?&lt;/span&gt;
&lt;span class="s"&gt;Yes&lt;/span&gt;

&lt;span class="pi"&gt;?&lt;/span&gt; &lt;span class="s"&gt;Add an HTTP header, e.g. Header-Name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;header value (leave blank for none)&lt;/span&gt;
&lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Basic ****************&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time we used the prefix &lt;code&gt;fauna_&lt;/code&gt; to prevent any naming conflicts in the types and operations, for example, the &lt;code&gt;Repository&lt;/code&gt; type from the GitHub GraphQL API and the &lt;code&gt;Repository&lt;/code&gt; type from the Fauna GraphQL API.&lt;/p&gt;

&lt;p&gt;After importing the Fauna GraphQL API, you can see the generated types and queries in the file &lt;code&gt;graphql-01/index.graphql&lt;/code&gt; in the project directory. The token for the Fauna GraphQL API is also stored in the &lt;code&gt;config.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Also, we can query the highlights from the Fauna GraphQL API from StepZen, as you can see in the screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-stepzen-graphiql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-stepzen-graphiql.png" alt="HTTP headers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final step is to compose the data from the two GraphQL APIs by combining them into one GraphQL API. This is done by adding a &lt;code&gt;extends.graphql&lt;/code&gt; file in the project directory, which will contain the types and queries that will be used to query the data from the two GraphQL APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compose data using StepZen
&lt;/h2&gt;

&lt;p&gt;We're now able to query both the GitHub GraphQL API and the Fauna GraphQL API individually using StepZen. To compose the data in one single GraphQL API, we'll create a new file called &lt;code&gt;extends.graphql&lt;/code&gt; file. This file will contain the types and queries that we will use to query the data from the two GraphQL APIs.&lt;/p&gt;

&lt;p&gt;Inside this new file, you should add the following code block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;extend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fauna_Repository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;githubDetails&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;github_Repository&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;materializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;github_repository&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will extend the type &lt;code&gt;fauna_Repository&lt;/code&gt;, which is the type &lt;code&gt;Repository&lt;/code&gt; from the Fauna GraphQL API, with all the fields returned by the query &lt;code&gt;github_repository&lt;/code&gt;. The query &lt;code&gt;github_repository&lt;/code&gt; is the query that is generated by the StepZen CLI when importing the GitHub GraphQL API. The arguments that are passed to the query are the fields &lt;code&gt;owner&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; from the &lt;code&gt;fauna_Repository&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;We can now use the &lt;code&gt;githubDetails&lt;/code&gt; field to query the GitHub GraphQL API, and we will use the &lt;code&gt;@materializer&lt;/code&gt; directive to query the &lt;code&gt;github_repository&lt;/code&gt; query from the GitHub GraphQL API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-materializer-query.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Ffauna-materializer-query.png" alt="Query with @materializer directive"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also query a single highlight and get all the other fields available on the return type of &lt;code&gt;github_repository&lt;/code&gt;, which is &lt;code&gt;github_Repository&lt;/code&gt;. StepZen will ensure that the data from the two GraphQL APIs are composed into one single GraphQL API, and no unnecessary data is requested or returned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we've used StepZen to combine the GitHub GraphQL API and the FaunaGraphQL API into one single GraphQL API. This makes it possible to query the data from both GraphQL APIs in one query. Composing data in GraphQL is also called federation. We've learned how to set up a GraphQL API with Fauna and fill it with data from GitHub, and how to use StepZen to combine the data from two GraphQL APIs into one single GraphQL API. And how to extend types with the &lt;code&gt;@materializer&lt;/code&gt; directive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You can find the complete code example for this blog post on the &lt;a href="https://github.com/stepzen-dev/examples/tree/main/with-fauna" rel="noopener noreferrer"&gt;StepZen GitHub page&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Follow StepZen on &lt;a href="https://twitter.com/stepzen_dev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://discord.gg/9k2VdPn2FR" rel="noopener noreferrer"&gt;join our Discord community&lt;/a&gt; to stay updated about our latest developments.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Extending types For Data Modelling in GraphQL</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Tue, 08 Nov 2022 18:35:14 +0000</pubDate>
      <link>https://forem.com/stepzen/extending-types-for-data-modelling-in-graphql-1db7</link>
      <guid>https://forem.com/stepzen/extending-types-for-data-modelling-in-graphql-1db7</guid>
      <description>&lt;p&gt;GraphQL is very good at helping you compose your data from different data sources, for example, by using &lt;a href="https://stepzen.com/product/federation"&gt;federation&lt;/a&gt;. Type extensions can be very helpful when you're using GraphQL as a data layer or gateway for all your data. GraphQL type extensions allow you to add or replace fields on types that already exist in your schema. This way, you can better organize your data from different sources.&lt;/p&gt;

&lt;p&gt;Let's explore how type extensions help with data modeling in GraphQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Type Extensions
&lt;/h2&gt;

&lt;p&gt;Type extensions help you with data modeling in GraphQL, primarily when you work with different data sources. Or want to modify third-party data types that you cannot change directly.&lt;/p&gt;

&lt;p&gt;In the GraphQL specification, you can find multiple definitions of type extensions, where "object extensions" are the most common ones. The section &lt;a href="http://spec.graphql.org/October2021/#sec-Object-Extensions"&gt;3.6.3. Object Extensions&lt;/a&gt; describes how you can use the &lt;code&gt;extend&lt;/code&gt; keyword to add or replace fields to an object type.&lt;/p&gt;

&lt;p&gt;An example of extending a type would be to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Person {
  id: String
  name: String
  age: Int
}

extend type Person {
  email: String
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The type &lt;code&gt;Person&lt;/code&gt; will now have the fields &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt;, and &lt;code&gt;email&lt;/code&gt;. When we go back to the earlier statement about data composition when working with multiple data sources, this example would be perfect for a situation where the fields &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, and &lt;code&gt;age&lt;/code&gt; come from one source of data (for example, a database). And &lt;code&gt;email&lt;/code&gt; comes from another data source, let's say a CRM.&lt;/p&gt;

&lt;p&gt;In StepZen, this means that the GraphQL schema would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Person {
  id: String
  name: String
  age: Int
}

extend type Person {
  email: String 
    @materializer (query: "getPersonEmail", arguments: [{name: "personId", field: "id"}]
}

type Query {
  getPerson(id: ID!): Person
    @dbquery(
      type: "mysql"
      table: "person"
      configuration: "mysql_config"
    )
  getPersonEmail(personId: ID!): String
    @rest (endpoint: "https://some.crm.com/api/person/$personId/email")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The GraphQL schema above will get the fields for the type &lt;code&gt;Person&lt;/code&gt; from the MySQL database using a &lt;code&gt;@dbquery&lt;/code&gt; connector. For the extended field &lt;code&gt;email&lt;/code&gt; it will use &lt;code&gt;@materializer&lt;/code&gt; to get the data from a CRM system using its REST API.&lt;/p&gt;

&lt;p&gt;If the database contained an &lt;code&gt;email&lt;/code&gt; field, it could also be overwritten when using type extensions, as StepZen will always prefer the extended object types.&lt;/p&gt;

&lt;p&gt;GraphQL also supports inheritance, which is often seen as an alternative to type extensions. Inheritance is focused on reusing rather than extending types, as you'll learn in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending types versus inheritance
&lt;/h2&gt;

&lt;p&gt;There's a difference between type extensions and inheritance. You can use inheritance to compose your data in many programming languages or type systems, and GraphQL is no different.&lt;/p&gt;

&lt;p&gt;With inheritance in GraphQL, you can reuse field definitions by using &lt;a href="https://stepzen.com/docs/connecting-backends/schemas-with-interfaces"&gt;interfaces&lt;/a&gt;, meaning you can assign a set of fields to every type that implements this interface. The implementations of this interface only share the types of the interface.&lt;/p&gt;

&lt;p&gt;Suppose you have a company that has both full-time employees and seasonal employees that only work in the winter or summer season.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Employee {
  id: ID
  name: String
  email: String
}

type FullTimeEmployee implements Employee {
  id: ID
  name: String
  email: String
  monthlyWage: Float
}

type SeasonalEmployee implements Employee {
  id: ID
  name: String
  email: String
  hourlyWage: Float
  season: String
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interface &lt;code&gt;Employee&lt;/code&gt; has the fields &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, and &lt;code&gt;email&lt;/code&gt;, which is the data the company stores for every employee for example in a database or CRM. Employees working full-time are paid a monthly wage, while a seasonal employee receives an hourly wage instead. Also, the company stores the season the employee is active in.&lt;/p&gt;

&lt;p&gt;As both &lt;code&gt;FullTimeEmployee&lt;/code&gt; and &lt;code&gt;SeasonalEmployee&lt;/code&gt; are implementing the interface &lt;code&gt;Employee&lt;/code&gt;, you have the certainty that the definitions of the fields &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, and &lt;code&gt;email&lt;/code&gt; are the same across all employees.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;GraphQL can be used as a data layer or gateway to compose this data when working with multiple data sources. Modeling your data in this setup can be done by using type extensions or, in some cases, by using inheritance. This post described how you could use object extensions to extend a type with fields coming from a different data source and inheritance to reuse field definitions for different ones.&lt;/p&gt;

&lt;p&gt;Want to try this out? Head over to the &lt;a href="https://stepzen.com/getting-started"&gt;Getting Started&lt;/a&gt; section and start building your GraphQL API. Follow us on &lt;a href="https://twitter.com/stepzen_dev"&gt;Twitter&lt;/a&gt; or &lt;a href="https://discord.gg/9k2VdPn2FR"&gt;join our Discord community&lt;/a&gt; to ask for help when you run into any issue.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Turn Your StepZen GraphQL APIs into REST with Kong</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Mon, 31 Oct 2022 10:32:40 +0000</pubDate>
      <link>https://forem.com/stepzen/turn-your-stepzen-graphql-apis-into-rest-with-kong-4209</link>
      <guid>https://forem.com/stepzen/turn-your-stepzen-graphql-apis-into-rest-with-kong-4209</guid>
      <description>&lt;p&gt;GraphQL APIs are becoming the defacto API standard. But what if you want to use a GraphQL API in a legacy application that only supports REST? This blog post will show you how to use Kong to turn your StepZen GraphQL APIs into REST. Earlier, we published a blog post about &lt;a href="https://stepzen.com/blog/cache-graphql-requests-kong-stepzen"&gt;how to use Kong as an API Gateway for StepZen GraphQL APIs&lt;/a&gt;, including using proxy caching. In this post, we will discuss another reason to use an API Gateway: to turn GraphQL APIs into REST API endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why turn GraphQL APIs (back) into REST?
&lt;/h2&gt;

&lt;p&gt;GraphQL is a great way to expose your data to your clients. It allows you to expose only the data your clients need and do so in a way that is easy to use. Although GraphQL might be the most efficient way to consume data in the frontend, it's not the only way to expose your data. REST is still a popular way to expose data, and many systems still rely on it. For example, when you need to integrate your API with a legacy system that only supports REST. Therefore, it might also make sense for your company to expose a REST API.&lt;/p&gt;

&lt;p&gt;One way to do so is by calling your GraphQL API the same way as a REST API. Most GraphQL APIs are implemented over HTTP, meaning that the request to a GraphQL API has the same structure as a request to a REST API. The only difference is that every request needs to be a &lt;code&gt;POST&lt;/code&gt; method and the request's body contains a GraphQL query.&lt;/p&gt;

&lt;p&gt;Another way is to use an API Gateway to turn your GraphQL API into a REST API. You define the REST API endpoints and map GraphQL queries to these endpoints. This is a more efficient way to expose your GraphQL API as a REST API because you can keep control of the available REST endpoints, and can distribute them to you clients much more like a contract (which REST also is). You can use the API Gateway to expose your GraphQL API as a REST API and to do other things like caching, rate limiting, and authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Kong to turn GraphQL APIs into REST APIs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://konghq.com/"&gt;Kong&lt;/a&gt; is an open-source API Gateway that you can use with all sorts of APIs, including GraphQL APIs. It helps you to manage your APIs and to do things like caching, rate limiting, and authentication. You can also use it to turn your GraphQL APIs into REST APIs, and we will go over how to do so.&lt;/p&gt;

&lt;p&gt;Let's say you have a GraphQL API that converts one currency to another, such as the &lt;a href="https://graphql.stepzen.com/frankfurter,ip-api"&gt;Frankfurter API&lt;/a&gt; in StepZen GraphQL Studio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="c"&gt;# https://graphqldd.stepzen.net/api/dd1cf47f51ac830fe21dc00ec80cee65/__graphql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConvertCurrencyByIP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;converted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ipApi_location&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;countryCode&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;priceInCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query can transform a currency based on the IP address. For example, if you want to convert 100 GBP to USD, you can do so by calling the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s1"&gt;'https://graphqldd.stepzen.net/api/dd1cf47f51ac830fe21dc00ec80cee65/__graphql'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'authority: graphqldd.stepzen.net'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'accept: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;$'{"query":"query ConvertCurrencyByIP($amount: Float&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s1"&gt;0021, $from: String&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s1"&gt;0021, $ip: String&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s1"&gt;0021) { converted: ipApi_location(ip: $ip) { countryCode price: priceInCountry(amount: $amount, from: $from) } }","variables":{"amount":100,"from":"GBP","ip":"8.8.8.8"},"operationName":"ConvertCurrencyByIP"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As StepZen has GraphQL implemented over HTTP, you could already use the call to this GraphQL like a REST API.&lt;/p&gt;

&lt;p&gt;However, if you want to use an API Gateway to turn your GraphQL API into a REST API, you can do so by using Kong. In &lt;a href="https://stepzen.com/blog/cache-graphql-requests-kong-stepzen"&gt;this article&lt;/a&gt; we explained how to use Kong as an API Gateway for a StepZen GraphQL API.&lt;/p&gt;

&lt;p&gt;The request will look the same when you're using Kong, but the endpoint will be different. Instead of calling the GraphQL endpoint, you will call the Kong endpoint. The Kong endpoint will then call the GraphQL endpoint and return the result to the client, in example if you have a local instance of Kong available on &lt;code&gt;localhost:8000&lt;/code&gt;, you can call the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8000/price/ &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"query": "query ($amount:Float!,$from:String!,$ip:String!){converted:ipApi_location(ip:$ip){countryCode price:priceInCountry(amount:$amount,from:$from)}}", "variables": {"amount":100,"from":"GBP","ip":"8.8.8.8"}}'&lt;/span&gt;

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"data"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"converted"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"countryCode"&lt;/span&gt;: &lt;span class="s2"&gt;"US"&lt;/span&gt;,
      &lt;span class="s2"&gt;"price"&lt;/span&gt;: 115.69
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To turn that query into a REST API endpoint, you can use the &lt;a href="https://docs.konghq.com/hub/kong-inc/degraphql/"&gt;degraphql plugin&lt;/a&gt; that's available for Kong Enterprise. With this plugin, you can create a REST API endpoint and declaratively map the GraphQL query to the REST endpoint. After configuring the plugin, you can call the following endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8001/services/graphql-demo/degraphql/routes &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="nv"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/gbp/:ip/:amount"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="nv"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'query($amount:Float!,$ip:String!){converted:ipApi_location(ip:$ip){countryCode price:priceInCountry(amount:$amount,from:"GBP")}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;uri&lt;/code&gt; parameter is used to create the REST endpoint you want to expose, where the &lt;code&gt;:ip&lt;/code&gt; and &lt;code&gt;:amount&lt;/code&gt; parameters are mapped to the parameters in the GraphQL query. The &lt;code&gt;query&lt;/code&gt; parameter is the GraphQL query you want to call.&lt;/p&gt;

&lt;p&gt;After registering the new REST endpoint to the plugin, you can call the following endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl localhost:8000/price/gbp/8.8.8.8/100

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"data"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"converted"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"countryCode"&lt;/span&gt;: &lt;span class="s2"&gt;"US"&lt;/span&gt;,
      &lt;span class="s2"&gt;"price"&lt;/span&gt;: 115.69
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the response has the same structure as earlier for our GraphQL query. This structure is typical for GraphQL APIs but not REST APIs and provides no benefits over calling the GraphQL API directly. To change this, you can "unwrap" the response by using the &lt;a href="https://docs.konghq.com/hub/kong-inc/jq/"&gt;jq plugin&lt;/a&gt; from Kong. You can configure this plugin to remove the &lt;code&gt;data&lt;/code&gt; key from the response and return the data directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="sb"&gt;`&lt;/span&gt;curl localhost:8001/services/graphql-demo/plugins &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;jq &lt;span class="nt"&gt;-d&lt;/span&gt; config.response_jq_program&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'.data'&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; config.request_if_media_type&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'application/json; charset=utf-8'&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you call the REST endpoint, you will get the following response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl localhost:8000/price/gbp/8.8.8.8/100

&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"converted"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"countryCode"&lt;/span&gt;:&lt;span class="s2"&gt;"US"&lt;/span&gt;,&lt;span class="s2"&gt;"price"&lt;/span&gt;:115.69&lt;span class="o"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a much better response for a REST API; you can use this to expose your GraphQL API as a REST API. For a more detailed explanation of how to use Kong to turn GraphQL APIs into REST APIs, you can read &lt;a href="https://konghq.com/blog/api-composition-with-stepzen-and-kong"&gt;this article&lt;/a&gt; on the Kong website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This post shows how you can use Kong to turn your GraphQL APIs into REST APIs. Even though GraphQL is becoming the standard for any client-facing API, many legacy systems still use REST APIs. Using Kong as an API Gateway got GraphQL, you can expose your GraphQL API as a REST API, which these legacy systems can use. This is done by mapping a GraphQL query to a REST endpoint and then using the Kong plugins to transform the response to a REST API response.&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://twitter.com/stepzen_dev"&gt;Twitter&lt;/a&gt; or &lt;a href="https://discord.gg/9k2VdPn2FR"&gt;join our Discord community&lt;/a&gt; to stay updated about our latest developments.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Implementing Cursor-based Pagination For Every GraphQL API</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Mon, 17 Oct 2022 12:02:26 +0000</pubDate>
      <link>https://forem.com/stepzen/implementing-cursor-based-pagination-for-every-graphql-api-2b3d</link>
      <guid>https://forem.com/stepzen/implementing-cursor-based-pagination-for-every-graphql-api-2b3d</guid>
      <description>&lt;h1&gt;
  
  
  Implementing Cursor-based Pagination For Every GraphQL API
&lt;/h1&gt;

&lt;p&gt;Backends often return a massive amount of data, and intaking all data simultaneously causes more overhead and increases the response time. Pagination preserves the application's performance by receiving small pieces of data in subsequent requests until the entire dataset is received.&lt;/p&gt;

&lt;p&gt;When Facebook publicly released GraphQL as a client-driven API-based query language, it quickly gained hype because it allowed front-end developers to modify their backends easily. Applications using GraphQL are more efficient and work promptly on slow networks, and therefore, it is quickly replacing the traditional API architectures like REST. Pagination is an essential concept in GraphQL, but there aren't many resources on pagination in GraphQL.&lt;/p&gt;

&lt;p&gt;In this post, we'll compare the different ways to handle pagination in GraphQL and learn how to configure a REST directive to perform cursor-based pagination for every REST API using StepZen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: You can find the complete documentation on paginating GraphQL using StepZen &lt;a href="https://stepzen.com/docs/connecting-backends/rest-services-graphql-pagination"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Comparing Different Methods of Pagination in GraphQL
&lt;/h2&gt;

&lt;p&gt;Pagination in GraphQL is not different from pagination in REST APIs, although some types of pagination better fit GraphQL. Before discussing the preferred pagination method in GraphQL, let's look at different pagination types. Typically, APIs offer three methods for pagination. These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://stepzen.com/blog#1-offset-pagination"&gt;Offset Pagination&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://stepzen.com/blog#2-page-number-pagination"&gt;Page Number Pagination&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://stepzen.com/blog#3-cursor-pagination"&gt;Cursor Pagination&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Offset Pagination
&lt;/h3&gt;

&lt;p&gt;Offset pagination consists of two primary parameters: limit and offset. The limit indicates the maximum number of results to show. And the offset denotes the position in the list from where the pagination starts.&lt;/p&gt;

&lt;p&gt;Suppose you have a list of 100 students. If you set the limit parameter to 10 and offset to 20, the database engine will count from the 20th student and display the following ten students in each iteration. For instance, the first iteration will show the students from 20 to 30, then from 30 to 40, etc.&lt;/p&gt;

&lt;p&gt;Although offset pagination is the most straightforward, it has a significant drawback. When some items are added or deleted, offset pagination results in repeated or missing data values.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  Most common way to do pagination in general.&lt;/li&gt;
&lt;li&gt;  Relatively simple implementation.&lt;/li&gt;
&lt;li&gt;  Most SQL-based databases support the limit and the offset variables, so it's easier to map values.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  Prone to data inconsistencies (repeated or missing data).&lt;/li&gt;
&lt;li&gt;  It doesn't provide information about more pages, total pages, or retrieval of previous pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Page Number Pagination
&lt;/h3&gt;

&lt;p&gt;As the name specifies, page number pagination returns a single page per request. You all have seen a "next page" option when working with tables; each sheet shows the same number of results or entries. Similarly, page number pagination returns the same number of results per request.&lt;/p&gt;

&lt;p&gt;Let's take an example to understand how it works. Page number pagination uses the after parameter to indicate the starting point for pagination. For instance, if you have a list of 30 students and set the after and the limit parameters to 23 and 5, respectively, then the output list will show a list of 5 students from the 23rd to 28th entry.&lt;/p&gt;

&lt;p&gt;Page number pagination is more reliable as the upcoming results start from the last fetched values.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  Easier to implement.&lt;/li&gt;
&lt;li&gt;  It doesn't require complex logical analysis.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  Data inconsistencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Cursor Pagination
&lt;/h3&gt;

&lt;p&gt;The third kind of pagination is cursor-based pagination. However, it is most complicated but is adaptable to dynamic data. Therefore, it is the preferred way to do pagination in GraphQL.&lt;/p&gt;

&lt;p&gt;This method includes a specific parameter for the cursor. A cursor is nothing but a reference point that shows the position of an item in the database. The data are represented as nodes and a cursor as an edge in the graphical representation.&lt;/p&gt;

&lt;p&gt;A cursor is a base64 encoded number. The query written for cursor-based pagination returns an object representation instead of a list.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  The preferred way to do pagination in GraphQL.&lt;/li&gt;
&lt;li&gt;  Provides valuable data for UX uses.&lt;/li&gt;
&lt;li&gt;  Allows reverse pagination.&lt;/li&gt;
&lt;li&gt;  No issues in the case of dynamic data as pagination are done to a specific row.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  It doesn't allow random access.&lt;/li&gt;
&lt;li&gt;  Needs complicated queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Implement Pagination in GraphQL using StepZen
&lt;/h2&gt;

&lt;p&gt;Now you know about all the possible pagination methods and the preferred way of doing pagination in GraphQL, which is cursor-based pagination. If your REST API supports offset or page number pagination, you can easily implement cursor-based pagination in GraphQL using StepZen.&lt;/p&gt;

&lt;p&gt;The two essential parameters you need to specify for every type of pagination are &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;setters&lt;/code&gt;. The &lt;code&gt;type&lt;/code&gt; parameters define the pagination style you want to implement. It has three possible values: &lt;code&gt;PAGE_NUMBER&lt;/code&gt;, &lt;code&gt;OFFSET&lt;/code&gt;, and &lt;code&gt;NEXT_CURSOR&lt;/code&gt;. Next comes the &lt;code&gt;setters&lt;/code&gt; parameters, which need to be pointed towards a field that indicates how many results or pages the response will output. You can find the list of all parameters with different pagination styles in the &lt;a href="https://stepzen.com/docs/connecting-backends/rest-services-graphql-pagination/"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's look at some examples:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Implementing Cursor Pagination for Offset
&lt;/h3&gt;

&lt;p&gt;The below snippet illustrates how to implement GraphQL cursor-based pagination using StepZen for REST APIs supporting offset pagination. Note that the parameter &lt;code&gt;first&lt;/code&gt; is set to the number of required results. The second parameter, &lt;code&gt;after&lt;/code&gt;, is set to the starting point of the pagination.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;customers(&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;first:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;after:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CustomerConnection&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;@rest(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;endpoint:"https://api.example.com/customers?limit=$first&amp;amp;offset=$after"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;pagination:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OFFSET&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;setters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_count&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since it's the first request, the &lt;code&gt;after&lt;/code&gt; parameter is equal to an empty string. The &lt;code&gt;first&lt;/code&gt; parameter is set to &lt;code&gt;20&lt;/code&gt;, which means that the first 20 results will be returned. On the second request, you can change the value for &lt;code&gt;after&lt;/code&gt; to be equal to the value of &lt;code&gt;first&lt;/code&gt; from the previous request. Every new request will be a multiple of the &lt;code&gt;first&lt;/code&gt; parameter.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Implementing Page Number Pagination
&lt;/h3&gt;

&lt;p&gt;Take a look at the following code to get a better understanding of implementing cursor-based pagination in GraphQL using StepZen, when your REST API is relying on page number pagination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;customers(&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;first:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;after:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CustomerConnection&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;@rest(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;endpoint:"https://api.example.com/customers?page=$after&amp;amp;per_page=$first"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;pagination:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NEXT_CURSOR&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;setters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;nextCursor&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above example illustrates some important aspects. The &lt;code&gt;after&lt;/code&gt; parameter is set to an empty string, which indicates that it is the first request. In contrast, the first parameter is set to &lt;code&gt;20&lt;/code&gt;, meaning that 20 results will be returned per page. Remember, the value of the first parameter remains the same for subsequent requests as well. The &lt;code&gt;after&lt;/code&gt; parameter in the upcoming request will be according to the page number you want to be returned. For instance, it is &lt;code&gt;3&lt;/code&gt; for the third and &lt;code&gt;4&lt;/code&gt; for the fourth page.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Implementing Cursor Pagination
&lt;/h3&gt;

&lt;p&gt;Implementing cursor-based pagination is very similar to the other two pagination methods. The only difference is that you need to specify the &lt;code&gt;type&lt;/code&gt; parameter as &lt;code&gt;NEXT_CURSOR&lt;/code&gt;, and change the setters parameter to point towards the field that indicates the next cursor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;customers(&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;first:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;after:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CustomerConnection&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;@rest(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;endpoint:"https://api.example.com/customers?first=$first&amp;amp;after=$after"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;pagination:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NEXT_CURSOR&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;setters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;nextCursor&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This, of course, only applies if your REST API already supports cursor-based pagination.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Query Cursor Pagination in GraphQL
&lt;/h2&gt;

&lt;p&gt;In the previous section, you've learned how to implement cursor-based pagination for any REST API using StepZen. Cursor-based pagination is for example, used by &lt;a href="https://relay.dev/graphql/connections.htm"&gt;Relay&lt;/a&gt;, and is also supported by the StepZen GraphQL API. Cursor-based pagination is the preferred way to do pagination in GraphQL, as it provides valuable data for UX uses. But it comes with the downside of being more complex to query, as we saw in the first section.&lt;/p&gt;

&lt;p&gt;Let's look at the &lt;code&gt;Connection&lt;/code&gt; type that is used by cursor-based pagination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;activities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Activity&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Contacts&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;designation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CustomerEdge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CustomerConnection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;pageInfo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PageInfo&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CustomerEdge&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;CustomerConnection&lt;/code&gt; type is the one that is returned by the &lt;code&gt;customers&lt;/code&gt; query. It contains a &lt;code&gt;pageInfo&lt;/code&gt; field, which is of type &lt;code&gt;PageInfo&lt;/code&gt;. The &lt;code&gt;PageInfo&lt;/code&gt; type contains the following fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyQuery&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;pageInfo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;endCursor&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;hasNextPage&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;hasPreviousPage&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;startCursor&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These fields inform you about the current page, and whether there are more pages to be fetched. The &lt;code&gt;endCursor&lt;/code&gt; and &lt;code&gt;startCursor&lt;/code&gt; fields are the cursors that you need to use in the next request. The &lt;code&gt;hasNextPage&lt;/code&gt; and &lt;code&gt;hasPreviousPage&lt;/code&gt; fields indicate whether there are more pages to be fetched.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;edges&lt;/code&gt; field contains a list of &lt;code&gt;CustomerEdge&lt;/code&gt; objects. The &lt;code&gt;CustomerEdge&lt;/code&gt; type contains a &lt;code&gt;node&lt;/code&gt; field of type &lt;code&gt;Customer&lt;/code&gt;. To get the information about the customer, you would need to use the &lt;code&gt;node&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyQuery&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eyJjIjoiTzpRdWVyeTpwYXJrcyIsIm8iOjl9"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The concept of "edges and nodes" is a bit confusing but very straightforward. It comes from the concept that everything in GraphQL is a graph. The &lt;code&gt;edges&lt;/code&gt; field contains a list of &lt;code&gt;CustomerEdge&lt;/code&gt; objects, information that is specific for this connection but not shared by all nodes. The &lt;code&gt;CustomerEdge&lt;/code&gt; type contains a &lt;code&gt;node&lt;/code&gt; field of type &lt;code&gt;Customer&lt;/code&gt;. This is the actual customer information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---0gRk1OI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/graphql-connections-edges-nodes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---0gRk1OI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/graphql-connections-edges-nodes.png" alt="Connections, Edges, and Nodes in GraphQL" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Relay, you can find more information on GraphQL connections in the &lt;a href="https://relay.dev/graphql/connections.htm"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;GraphQL allows different kinds of pagination. But how does one decide which one will work best? GraphQL recommends using cursor-based pagination. However, it depends on the requirements of your application. If you are using a REST API already supporting cursor-based pagination, then it's a no-brainer. But if you are using a REST API that is not supporting cursor-based pagination, then you can use StepZen to implement it.&lt;/p&gt;

&lt;p&gt;The common and the most straightforward kinds of pagination are &lt;strong&gt;offset&lt;/strong&gt; and &lt;strong&gt;page number&lt;/strong&gt;. Although they are relatively simple to implement, they are more suitable for static data. In contrast, &lt;strong&gt;cursor-based pagination&lt;/strong&gt; is complex but best for changing data as it prevents data inconsistencies. With StepZen, it's straightforward to implement cursor-based pagination for any API.&lt;/p&gt;

&lt;p&gt;Learn more by visiting &lt;a href="https://stepzen.com/docs/quick-start"&gt;StepZen Docs&lt;/a&gt;. Try it out with a &lt;a href="https://stepzen.com/signup"&gt;free account&lt;/a&gt;, and we'd love to get your feedback and answer any questions on our &lt;a href="https://discord.com/invite/9k2VdPn2FR"&gt;Discord&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Generate a GraphQL API For Amazon RDS PostgreSQL With StepZen</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Thu, 13 Oct 2022 09:16:02 +0000</pubDate>
      <link>https://forem.com/stepzen/generate-a-graphql-api-for-amazon-rds-postgresql-with-stepzen-50jn</link>
      <guid>https://forem.com/stepzen/generate-a-graphql-api-for-amazon-rds-postgresql-with-stepzen-50jn</guid>
      <description>&lt;p&gt;StepZen is a GraphQL-as-a-Service cloud infrastructure that helps you to build and deploy scalable, secured, and performant GraphQL APIs from different data sources. With StepZen, you can get your GraphQL API up and running from a database (MySQL, PostgreSQL, NoSQL) or an existing REST or GraphQL API.&lt;/p&gt;

&lt;p&gt;In this post, you'll learn how to use StepZen with an Amazon RDS database based on PostgreSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Amazon (AWS) RDS databases
&lt;/h2&gt;

&lt;p&gt;Amazon Web Services Relational Database System (or AWS RDS PostgreSQL) is a cloud-based relational database system that makes it easier to set up, operate, and scale a relational database in the cloud. Amazon RDS databases offer a high availability for PostgreSQL, making them a perfect fit for usage in high-traffic production environments. Next to high availability, you can easily deploy new databases, get backup and recovery options, plus enhanced security as opposed to running a PostgreSQL database on-premise.&lt;/p&gt;

&lt;p&gt;There's a huge benefit in using AWS RDS together with StepZen, as both services run in the cloud and are optimized for performance. GraphQL APIs created with StepZen are scaled automatically to meet the traffic demands of your API. So you don't have to worry about your API’s traffic and security because StepZen has got you covered! On the other hand, AWS RDS makes sure your database won't be a bottleneck when you experience increased traffic from your GraphQL API.&lt;/p&gt;

&lt;p&gt;This post will show how to generate a GraphQL API for AWS RDS PostgreSQL using StepZen. Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up AWS RDS Setup: Creating and connecting a PostgreSQL database with Amazon’s Relational Database Service (RDS)
&lt;/h2&gt;

&lt;p&gt;We will learn how to create and connect a PostgreSQL database to a cloud-based database management system. This was normally a daunting task, but it is now a straightforward thing to do, all thanks to AWS.&lt;/p&gt;

&lt;p&gt;You can create and deploy six relational databases to Amazon Web Service through their RDS web products. The database engines supported by RDS include MariaDB, Oracle Database, MySQL, SQL Server, Amazon Aurora, and of course PostgreSQL.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Sign up for an Amazon Web Services account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Creating an Amazon Web Service account is very easy. All you need to do is go to &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;aws.amazon.com&lt;/a&gt;. The landing page of this website is generic, like other sites. All you have to do now is click on "Create AWS account."&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Create an RDS instance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After creating your AWS account, go to services located in the upper left corner or footer. Click on it and select RDS. After selecting RDS, you’ll be prompted to select a relational database engine. In this case, we’ll be using the PostgreSQL database engine. You’ll also notice a drop-down menu where you can select the database version. Select the most recent version, or at least the second most recent.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Configure your Database Instance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At this point, you're expected to give your database instance a name and set a master username and password. The password and username you set here are used for local and cloud database interaction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-create-postgresql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-create-postgresql.png" alt="Amazon Web Services RDS create instance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selecting "PostgreSQL" as the database engine, you need to configure the database instance size, availability, and storage. Though it’s always good to make personalized choices, you should leave everything in the default settings at this point in AWS database creation, and this is simply because the best choices have already been ticked by default. Finally, click on "Create Database."&lt;/p&gt;

&lt;p&gt;We will have to wait for some time so that AWS can finish setting up our newly created database. This process usually doesn’t take more than 10 minutes. And boom! Our database is ready!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’re done creating our database. It is now time to connect our cloud database to our local PostgreSQL. We’ll be using pgAdmin 4 as our local PostgreSQL development environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration of pgAdmin and AWS PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Connecting PostgreSQL databases to AWS is straightforward. All you have to do is get the connection credentials readily available at "view connection details". The only information you require from AWS is the port number, host endpoint, username, and some security group configurations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Copy Login Credentials from "Connection Details"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;All the details you need to connect to the new AWS RDS PostgreSQL database are already available after database instance creation. The next thing to do is to click on the security group bar and look for inbound rules. To avoid disrupting the PostgreSQL-AWS connection, click on the Edit inbound rule and select "Anywhere."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-postgresql-credentials.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-postgresql-credentials.png" alt="Amazon Web Services RDS copy credentials"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Download and install pgAdmin or the EDB PostgreSQL Suite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can download pgAdmin from their &lt;a href="http://pgadmin.org/" rel="noopener noreferrer"&gt;official website&lt;/a&gt;. The same is true for PostgreSQL from EDB. The setup is basically straightforward, and just click on the installer and wait for the program to finish installing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Launch pgAdmin and connect to AWS database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Launch the already installed pgAdmin like any application. Right-click on the server object in the pgAdmin and click on "create".&lt;/p&gt;

&lt;p&gt;Enter the name of your database instance and click on the connection tab. Enter the login credentials from the AWS RDS console and finally click on "save".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-pgadmin-setup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-pgadmin-setup.png" alt="Set up AWS RDS in pgAdmin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your workspace should have some changes by now and include a schema for the PostgreSQL database.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's continue by adding data to this database in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Data to AWS RDS using pgAdmin
&lt;/h2&gt;

&lt;p&gt;We're almost done setting up the database. It's time to add some data into our AWS RDS database, which we will use to create our GraphQL schema with StepZen. For this, we'll again be using pgAdmin, which we've already set up in the previous section.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can also use other tools to add data to a PostgreSQL database, for example directly from the command line with &lt;a href="https://www.postgresql.org/docs/current/app-psql.html" rel="noopener noreferrer"&gt;psql&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will use a couple of products as data for our database. Each product has its &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, &lt;code&gt;quantity&lt;/code&gt;, and their unique &lt;code&gt;IDs. To achieve this, we’ll create a table named&lt;/code&gt; Products`. With the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;area&lt;/code&gt;: The area of our table is &lt;code&gt;Products&lt;/code&gt;, since we will be storing product data.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;id&lt;/code&gt;: This serves our primary key.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;description&lt;/code&gt;: Which carries the name of our product.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;quantity&lt;/code&gt;: Which shows the quantity of each product.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;price&lt;/code&gt;: This column carries the price of each product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CSV data below contains the data used in our database columns:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;csv&lt;br&gt;
"area","id","description","quantity","price"&lt;br&gt;
"Product",1,"Rice",20,120&lt;br&gt;
"Product",2,"Bread",400,5&lt;br&gt;
"Product",3,"Oysters",35,50&lt;br&gt;
"Product",4,"Beans",10,3&lt;br&gt;
"Product",5,"Grape",456,23&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Adding data to our remote database is the same as with local databases, and all you have to do is to locate the "table" in your workspace.&lt;/p&gt;

&lt;p&gt;Click on it and then click on "Create a new table". Create a table name and then click on the column bar. You're going to add your table columns here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-pgadmin-new-table.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-pgadmin-new-table.png" alt="Set up AWS RDS in pgAdmin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To view and edit table data, just right-click on your table name and select “View and Edit Data.” The image below shows the column and row data we used in our Postgres.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-pgadmin-table-data.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-pgadmin-table-data.png" alt="View and edit data in pgAdmin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating the table data, click "refresh" to synchronize your primary database. This will ensure that all new changes are pushed to AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating a GraphQL Schema from AWS RDS
&lt;/h2&gt;

&lt;p&gt;Now that we have our database set up, it’s time to generate a GraphQL schema. We’ll be using StepZen to generate our GraphQL schema. StepZen is a GraphQL API service that allows you to connect to any data source and generate a GraphQL schema from it that you can deploy to the cloud.&lt;/p&gt;

&lt;p&gt;To use StepZen, you need to install the CLI. The installation process of StepZen CLI is not a difficult one. All you have to do is to use the following npm commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
&lt;/code&gt;npm install -g stepzen`&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make sure to have Node.js installed on your machine, as it's used as the runtime for the CLI. After installing the CLI, you can generate a GraphQL schema from your AWS RDS database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Create a StepZen account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To use StepZen CLI, you must create an account just like we did during the AWS setup. You can create an account &lt;a href="https://stepzen.com/signup" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Then go to your &lt;a href="https://dashboard.stepzen.com/" rel="noopener noreferrer"&gt;StepZen dashboard&lt;/a&gt;, where you can monitor the APIs you've deployed and access the login details you need for StepZen's CLI.&lt;/p&gt;

&lt;p&gt;You can get your username and API key from your &lt;a href="https://dashboard.stepzen.com/account" rel="noopener noreferrer"&gt;My StepZen - Authentication&lt;/a&gt; tab. You'll need these credentials to log in to the StepZen CLI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Login in the StepZen CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To login to the StepZen CLI, you need to use the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
&lt;/code&gt;stepzen login`&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will prompt you to enter your username and API key. After entering the credentials, you'll be logged in to the StepZen CLI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Use StepZen to import AWS RDS PostgreSQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;StepZen has made it simple to import databases from different sources; AWS RDS PostgreSQL is no exception. All you have to do is to use the commands below. The credentials for Amazon RDS PostgreSQL are the same as the ones we used to connect to pgAdmin.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
$ stepzen import postgresql&lt;/p&gt;

&lt;p&gt;? What would you like your endpoint to be called? (api/product-list)&lt;/p&gt;

&lt;p&gt;Downloading from StepZen...... done&lt;/p&gt;

&lt;p&gt;? What is your host? &lt;/p&gt;

&lt;p&gt;? What is your database name? &lt;/p&gt;

&lt;p&gt;? What is the username? &lt;/p&gt;

&lt;p&gt;? What is the password? [hidden] &lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;StepZen will automatically create a GraphQL schema for your PostgreSQL database with a set of sample queries and mutations if the process is successful.&lt;/p&gt;

&lt;p&gt;If you open the directory created from the above StepZen commands, you're going to see the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;postgresql/index.graphql&lt;/code&gt;: This file contains the GraphQL schema for your database.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;index.graphql&lt;/code&gt;: This file contains the index of all GraphQL schemas in case you're using multiple data sources.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;config.yaml&lt;/code&gt;: This is where our database configuration files are located.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;stepzen.config.json&lt;/code&gt;: This is where our StepZen endpoint is located. You can also see it on your StepZen dashboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's deploy these files to the StepZen cloud in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying the GraphQL Schema to StepZen
&lt;/h2&gt;

&lt;p&gt;So far, we've set up a PostgreSQL database using AWS RDS, seeded it with data, and created a GraphQL schema for this database. This means we're almost done. Deploying the GraphQL API is the last step, and all you have to do is to type the command below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
&lt;/code&gt;stepzen start`&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will deploy our GraphQL schema to the endpoint in &lt;code&gt;stepzen.config.json&lt;/code&gt;. A link will be generated for you at the terminal. The URL for local exploration of your GraphQL API using GraphiQL looks something like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;html&lt;br&gt;
&lt;/code&gt;&lt;a href="http://localhost:5001/api/product-list%60" rel="noopener noreferrer"&gt;http://localhost:5001/api/product-list`&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can then test your GraphQL API after the link opens. You can also monitor the number of queries and requests made through the endpoint in your StepZen dashboard, the data in the dashboard is updated every day.&lt;/p&gt;

&lt;p&gt;The GraphQL schema that we generated from our database has the queries as seen below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;graphql&lt;br&gt;
"""&lt;br&gt;
These are some examples of queries generated from the schema. Feel free to modify them or add your own.&lt;br&gt;
"""&lt;br&gt;
type Query {&lt;br&gt;
  getProductsList: [Products]&lt;br&gt;
    @dbquery(&lt;br&gt;
      type: "postgresql"&lt;br&gt;
      schema: "public"&lt;br&gt;
      table: "Products"&lt;br&gt;
      configuration: "postgresql_config"&lt;br&gt;
    )&lt;br&gt;
  getProducts(id: Int!): Products&lt;br&gt;
    @dbquery(&lt;br&gt;
      type: "postgresql"&lt;br&gt;
      schema: "public"&lt;br&gt;
      table: "Products"&lt;br&gt;
      configuration: "postgresql_config"&lt;br&gt;
    )&lt;/code&gt;&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can query our database using the &lt;code&gt;getProductsList&lt;/code&gt; and &lt;code&gt;getProducts&lt;/code&gt; queries. The &lt;code&gt;getProductsList&lt;/code&gt; query returns all the data in the database, while the &lt;code&gt;getProducts&lt;/code&gt; query returns a single row of data from the database.&lt;/p&gt;

&lt;p&gt;This code below will query for the description of the products in our database:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;graphql&lt;br&gt;
{&lt;br&gt;
  getProductsList {&lt;br&gt;
    description&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The response will be a JSON response that includes the description of the products in our database. You can also request fields like the &lt;code&gt;price&lt;/code&gt; or &lt;code&gt;quantity&lt;/code&gt; for every product. From GraphiQL, it will look like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-stepzen-graphiql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Faws-rds-stepzen-graphiql.png" alt="StepZen dashboard with your account data"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From GraphiQL, you can also explore the GraphQL schema and test out the queries and mutations. You can also use the StepZen GraphQL API to build a frontend application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This post taught you how to generate a GraphQL API for an AWS RDS PostgreSQL database. We have covered how to set up and connect pgAdmin to AWS RDS PostgreSQL, install StepZen, import data from AWS RDS, and deploy and query StepZen GraphQL API.&lt;/p&gt;

&lt;p&gt;Want to learn more about &lt;a href="https://stepzen.com/docs/quick-start" rel="noopener noreferrer"&gt;StepZen&lt;/a&gt;? Try it out here or ask any question on the Discord &lt;a href="https://discord.com/invite/9k2VdPn2FR" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Join us for Hacktoberfest 2022 by contributing to StepZen</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Wed, 28 Sep 2022 16:45:26 +0000</pubDate>
      <link>https://forem.com/stepzen/join-us-for-hacktoberfest-2022-by-contributing-to-stepzen-4dkh</link>
      <guid>https://forem.com/stepzen/join-us-for-hacktoberfest-2022-by-contributing-to-stepzen-4dkh</guid>
      <description>&lt;p&gt;Hacktoberfest 2022 is about to start! Join us for the latest edition of Hacktoberfest by contributing to StepZen. We're looking for contributors to help us create new integrations and improve existing ones. Contributors will receive limited StepZen goodies and Hacktoberfest swag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hacktoberfest 2022
&lt;/h2&gt;

&lt;p&gt;Hacktoberfest is a celebration of open-source software. It's a month-long event that takes place every October. The goal of Hacktoberfest is to encourage developers to contribute to open-source projects. Hacktoberfest is open to everyone in our global community. You can sign up anytime between September 26 and October 31 via the &lt;a href="https://hacktoberfest.com/"&gt;Hacktoberfest website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Everyone that signs up for Hacktoberfest &lt;a href="https://hacktoberfest.com/auth/"&gt;here&lt;/a&gt; has to make four pull requests (PRs) to public repositories on GitHub (or Gitlab). You can make pull requests to any public repository on GitHub with issues labeled &lt;code&gt;hacktoberfest&lt;/code&gt;. Once approved and merged by the repository maintainers, your pull requests count towards your Hacktoberfest goals.&lt;/p&gt;

&lt;p&gt;If you complete four pull requests in October, you'll receive a free Hacktoberfest t-shirt and a limited edition Hacktoberfest 2022 sticker pack. You can find more information about Hacktoberfest on the &lt;a href="https://hacktoberfest.digitalocean.com/"&gt;Hacktoberfest website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contribute to StepZen
&lt;/h2&gt;

&lt;p&gt;StepZen is participating in Hacktoberfest, and you can contribute by adding a new integration or improving an existing integration in our &lt;a href="https://github.com/stepzen-dev/examples"&gt;Examples repository&lt;/a&gt;. Every PR to this repository will count towards your Hacktoberfest goals.&lt;/p&gt;

&lt;p&gt;In this repository, you'll find two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Examples of how to use StepZen to build a GraphQL API by integrating with databases or external APIs.&lt;/li&gt;
&lt;li&gt;  Usage of a StepZen API in a (frontend) application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We're looking for contributors to help us create new integrations and improve existing ones. You can find a list of integrations that we're looking for in the &lt;a href="https://github.com/stepzen-dev/examples/issues"&gt;issues&lt;/a&gt; for the repository, including a list of improvements to existing integrations. But we encourage you also to open a new issue and PR for other integrations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next to being eligible for the official Hacktoberfest, we'll ship StepZen goodies to contributors. Read the &lt;a href="https://github.com/stepzen-dev/examples/blob/main/CONTRIBUTING.md"&gt;contributing guidelines&lt;/a&gt; before creating a PR.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keep an eye out for new features and more integrations on our &lt;a href="https://twitter.com/stepzen_dev"&gt;Twitter&lt;/a&gt; page and &lt;a href="https://discord.gg/9k2VdPn2FR"&gt;Discord&lt;/a&gt; community.&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>graphql</category>
    </item>
    <item>
      <title>How to Cache GraphQL Requests Using Kong and StepZen</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Thu, 22 Sep 2022 15:52:47 +0000</pubDate>
      <link>https://forem.com/stepzen/how-to-cache-graphql-requests-using-kong-and-stepzen-4gk9</link>
      <guid>https://forem.com/stepzen/how-to-cache-graphql-requests-using-kong-and-stepzen-4gk9</guid>
      <description>&lt;p&gt;GraphQL is often used as an API gateway for microservices, but can also play nicely with existing solutions for API gateways. For example using &lt;a href="https://konghq.com/" rel="noopener noreferrer"&gt;Kong&lt;/a&gt;, an API gateway and microservice management platform. As an API Gateway, Kong has many capabilities that you can use to enhance GraphQL APIs. One of those capabilities is adding a proxy cache to the upstream services you add to Kong. But when it comes to caching with GraphQL, there are several caveats you must consider due to the nature of GraphQL. In this post, we will go over the challenges of caching a GraphQL API and how an API gateway can help with this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use API Caching?
&lt;/h2&gt;

&lt;p&gt;Caching is an important part of any API — you want to ensure that your users get the best response time on their requests as possible. Of course, caching is not a one-size-fits-all solution, and there are a lot of different strategies for different scenarios.&lt;/p&gt;

&lt;p&gt;Suppose your API is a high-traffic, critical application. It's going to get hit hard by many users, and you want to make sure it can scale with demand. Caching can help you do that by reducing the load on your servers and improving all users' performance while potentially reducing costs and providing additional security features. Caching with Kong is often applied at the proxy layer, meaning that this proxy will cache requests and serve the response of the last call to an endpoint if this exists in the cache.&lt;/p&gt;

&lt;p&gt;GraphQL APIs have their challenges in caching that you need to be aware of before implementing a caching strategy, as you'll learn in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges of Caching with GraphQL
&lt;/h2&gt;

&lt;p&gt;GraphQL has been getting increasingly popular amongst companies. GraphQL is best described as a query language for APIs. It's declarative, which means you write what you want your data to look like and leave the details of that request up to the server. This is good for us because it makes our code more readable and maintainable by separating concerns into client-side and server-side implementations.&lt;/p&gt;

&lt;p&gt;GraphQL APIs can solve challenges like over fetching and under fetching (also called the N+1 problem). But as with any API, a poorly designed GraphQL API can result in some horrendous N+1 issues. Users have control over the response of a GraphQL request by modifying the query they send to the GraphQL API, and they can even make the data nested on multiple levels. While there are certainly ways to alleviate this problem on the backend via the design of the resolvers or caching strategies, what if there was a way to make your GraphQL API blazing fast without changing a single line of code?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;StepZen adds caching to queries and mutations that rely on &lt;code&gt;@rest&lt;/code&gt;, see &lt;a href="https://stepzen.com/docs/custom-graphql-directives/directives#cachepolicy" rel="noopener noreferrer"&gt;here&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By using Kong and GraphQL Proxy Cache Advanced plugin, you totally can! Let's take a look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up caching for GraphQL with Kong
&lt;/h2&gt;

&lt;p&gt;When you're using Kong as an API gateway, it can be used to proxy requests to your upstream services, including GraphQL APIs. With the enterprise plugin &lt;a href="https://docs.konghq.com/hub/kong-inc/graphql-proxy-cache-advanced/" rel="noopener noreferrer"&gt;GraphQL Proxy Caching Advanced&lt;/a&gt;, you can add proxy caching to any GraphQL API. With this plugin, you can enable proxy caching on the GraphQL service, route, or even globally. Let's try this out by adding a GraphQL service to Kong created with StepZen.&lt;/p&gt;

&lt;p&gt;With StepZen, you can create GraphQL APIs declaratively by using the CLI or writing GraphQL SDL (Scheme Definition Language). It's a language-agnostic way to create GraphQL as it relies completely on the GraphQL SDL. The only thing you need to get started is an existing data source, for example, a (No)SQL database or a REST API. You can then generate a schema and resolvers for this data source using the CLI or write the connections using GraphQL SDL. The GraphQL schema can then be deployed to the cloud directly from your terminal, with built-in authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a GraphQL API using StepZen
&lt;/h3&gt;

&lt;p&gt;To get a GraphQL using StepZen, you can connect your data source or use one of the pre-built examples from Github. In this post, we'll be taking a GraphQL API created on &lt;a href="https://github.com/stepzen-dev/examples/tree/main/with-mysql" rel="noopener noreferrer"&gt;top off a MySQL database&lt;/a&gt; from the examples. By cloning this repository to your local machine, you'll get a set of configuration files and &lt;code&gt;.graphql&lt;/code&gt; files containing the GraphQL schema. To run the GraphQL API and deploy it to the cloud, you need to be using the StepZen CLI.&lt;/p&gt;

&lt;p&gt;You can install the CLI from npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`npm i -g stepzen`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing the CLI, you can &lt;a href="https://stepzen.com/signup" rel="noopener noreferrer"&gt;sign-up for a StepZen account&lt;/a&gt; to deploy the GraphQL API on a private, secured endpoint. Optionally, you can continue without signing up but bear in mind that the deployed GraphQL endpoint will be public. To start and deploy the GraphQL API, you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`stepzen start`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this command will return a deployed endpoint in your terminal (like &lt;code&gt;https://public3b47822a17c9dda6.stepzen.net/api/with-mysql/__graphql&lt;/code&gt;). Also, it produces a &lt;code&gt;localhost&lt;/code&gt; address that you can use to explore the GraphQL API locally using GraphiQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a GraphQL Service to Kong
&lt;/h3&gt;

&lt;p&gt;The service you've created in the previous section can now be added to your Kong gateway by using Kong Manager or the &lt;a href="https://docs.konghq.com/gateway/latest/configure/graphql-quickstart/#existing-graphql-infrastructure" rel="noopener noreferrer"&gt;Admin API&lt;/a&gt;. Let's use the Admin API to add our newly created GraphQL API to Kong, which only requires us to send a few cURL requests. First, we need to add the service, and then a route for this service needs to be added.&lt;/p&gt;

&lt;p&gt;You can run the following command to add the GraphQL service and route. Depending on the setup of your Kong gateway, you might need to add authentication headers to your request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -i -X POST \
  --url http://localhost:8001/services/ \
  --data 'name=graphql-service' \
  --data 'url=https://public3b47822a17c9dda6.stepzen.net/api/with-mysql/__graphql'

curl -i -X POST \
  --url http://localhost:8001/services/graphql-service/routes \
  --data 'hosts[]=stepzen.net' \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The GraphQL API has now been added as an upstream service to the Kong gateway, meaning you can already proxy to it. But not before we'll be adding the &lt;a href="https://docs.konghq.com/hub/kong-inc/graphql-proxy-cache-advanced/" rel="noopener noreferrer"&gt;GraphQL Proxy Caching Advanced&lt;/a&gt; plugin to it, which can also be done using a cURL command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;​​curl -i -X POST \
  --url http://localhost:8001/services/graphql-service/plugins/ \
  --data 'name=graphql-proxy-cache-advanced' \
  --data 'config.strategy=memory'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Kong as a proxy for the GraphQL API with the addition of this plugin, all requests are cached automatically at the query level. The default TTL (Time To Live) of the cache is 300 seconds unless you overwrite it (for example 600 seconds) by adding &lt;code&gt;--data' config.cache_ttl=600&lt;/code&gt;. In the next section, we'll explore the cache by querying the proxied GraphQL endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying a GraphQL API
&lt;/h2&gt;

&lt;p&gt;The proxied GraphQL API will be available through Kong on your gateway endpoint. When you send a request to it, it will expect to receive a header value with the hostname of the GraphQL. As it is a request to a GraphQL API, keep in mind that all requests should be &lt;code&gt;POST&lt;/code&gt; requests with the &lt;code&gt;Content-Type: application/json&lt;/code&gt; header and a GraphQL query appended in the body.&lt;/p&gt;

&lt;p&gt;To send a request to the GraphQL API, you must first construct a GraphQL query. When you visit the endpoint where the GraphQL API is deployed, you find a GraphiQL interface - an interactive playground to explore the GraphQL API. In this interface, you can find the complete schema, including the queries and possibly other operations the GraphQL API accepts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Fstepzen-kong-api-gateway-graphiql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstepzen.com%2Fimages%2Fblog%2Fstepzen-kong-api-gateway-graphiql.png" alt="GraphiQL interface for a StepZen GraphQL API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this interface, you can send queries and explore the result and the schema as you see above. To send this same query to the proxied GraphQL API, you can use the following cURL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -i -X POST 'http://localhost:8000/' \
--header 'Host: stepzen.net' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"query getCustomerList {\n getCustomerList {\n name\n }\n}","variables":{}}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This cURL will return both the response result and the response headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 445
Connection: keep-alive
X-Cache-Key: 5abfc9adc50491d0a264f1e289f4ab1a
X-Cache-Status: Miss
StepZen-Trace: 410b35b512a622aeffa2c7dd6189cd15
Vary: Origin
Date: Wed, 22 Jun 2022 14:12:23 GMT
Via: kong/2.8.1.0-enterprise-edition
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
X-Kong-Upstream-Latency: 256
X-Kong-Proxy-Latency: 39

{
  "data": {
    "getCustomerList": [
      {
        "name": "Lucas Bill"
      },
      {
        "name": "Mandy Jones"
      },
      …
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above, the response of the GraphQL API can be seen, which is a list of fake customers with the same data structure as the query we sent to it. Also, the response headers are outputted, and here are two headers that we should focus on: &lt;code&gt;X-Cache-Status&lt;/code&gt; and &lt;code&gt;X-Cache-Key&lt;/code&gt;. The first header will show if the cache was hit, and the second shows the key of the cached response. To cache the response, Kong will look at the endpoint you send the request to and the contents of the post body - which includes the query and possible query parameters. The GraphQL Proxy Advanced Plugin doesn't cache part of the response if you reuse parts of a GraphQL query in a different request.&lt;/p&gt;

&lt;p&gt;On the first request, the value for &lt;code&gt;X-Cache-Status&lt;/code&gt; will always be &lt;code&gt;Miss&lt;/code&gt; as no cached response is available. However, &lt;code&gt;X-Cache-Key&lt;/code&gt; will always have a value as a cache will be created on the request. Thus the value for &lt;code&gt;X-Cache-Key&lt;/code&gt; will be the key of the newly created cached response or the existing cache response from a previous request.&lt;/p&gt;

&lt;p&gt;Let's make this request again and focus on the values of these two response headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X-Cache-Status: Hit
X-Cache-Key: 5abfc9adc50491d0a264f1e289f4ab1a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second time we hit the proxied GraphQL API endpoint, the cache was hit, and the cache key is still the same value as for the first request. This means the previous request's response has been cached and is now returned. Instead, the cached response was served as the cache status indicated. Unless you change the default TTL of the cache, the cached response stays available for 300 seconds. If you send this same request to the proxied GraphQL API after the TTL expires, the cache status will be &lt;code&gt;Miss&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can also inspect the cached response directly by sending a request to the GraphQL Proxy Advanced Plugin directly. To get the cached response from the previous request, you can use the following endpoint on the Admin API of your Kong instance. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`curl http://localhost:8001/graphql-proxy-cache-advanced/5abfc9adc50491d0a264f1e289f4ab1a`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This request returns &lt;code&gt;HTTP 200 OK&lt;/code&gt; if the cached value exists and &lt;code&gt;HTTP 404 Not Found&lt;/code&gt; if it doesn't. Using the Kong Admin API, you can delete a cached response by its key or even purge all cached responses. See the &lt;a href="https://docs.konghq.com/hub/kong-inc/graphql-proxy-cache-advanced/#delete-cache-entity" rel="noopener noreferrer"&gt;Delete cached entity section&lt;/a&gt; in the GraphQL Proxy Cache Advanced documentation for more information on this subject.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This post taught you how to add a GraphQL API to Kong to create a proxied GraphQL endpoint. By adding it to Kong, you don't only get all the features that Kong offers as a proxy service, but you can also implement caching for the GraphQL API. You can do this by installing the GraphQL Proxy Cache Advanced, which is available for Plus and Enterprise instances. With this plugin, you can implement proxy caching for GraphQL APIs, letting you cache the response of any GraphQL request.&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://twitter.com/stepzen_dev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://discord.gg/9k2VdPn2FR" rel="noopener noreferrer"&gt;join our Discord community&lt;/a&gt; to stay updated about our latest developments.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Announcing Local Development of StepZen GraphQL APIs with Docker</title>
      <dc:creator>Roy Derks</dc:creator>
      <pubDate>Fri, 16 Sep 2022 11:57:45 +0000</pubDate>
      <link>https://forem.com/stepzen/announcing-local-development-of-stepzen-graphql-apis-with-docker-1a5m</link>
      <guid>https://forem.com/stepzen/announcing-local-development-of-stepzen-graphql-apis-with-docker-1a5m</guid>
      <description>&lt;p&gt;Announcement! Everyone can now locally develop GraphQL APIs with Docker. So far only enterprise customers have been able to run StepZen locally, but this option is now available to everyone.&lt;/p&gt;

&lt;p&gt;At StepZen we want to make it as simple as possible to create a secure, and performant GraphQL API. Being able to locally develop and run your APIs is vital when you're building a new service, and this latest feature will make that possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Docker for local development
&lt;/h2&gt;

&lt;p&gt;Running StepZen locally has many benefits. For example, you can run your GraphQL API on your local machine, and connect to your local database. This is useful when you're developing a new GraphQL API, and want to test it locally before deploying it to a public or private cloud.&lt;/p&gt;

&lt;p&gt;This new feature is available from the &lt;a href="https://www.npmjs.com/package/stepzen"&gt;StepZen CLI&lt;/a&gt; version 0.21.0 which you can download from npm. With the CLI you can create, run and deploy GraphQL APIs directly from your terminal or command line.&lt;/p&gt;

&lt;p&gt;By default the StepZen CLI runs your GraphQL as a managed service on Google Cloud, where your GraphQL API is optimized for performance and security. Or to a &lt;a href="https://stepzen.com/docs/deployment/private-cloud/"&gt;private cloud&lt;/a&gt; for enterprise customers.&lt;/p&gt;

&lt;p&gt;But this same CLI can now also be used to locally run your GraphQL CLI using Docker. Instead of deploying it to a public or private cloud, your local machine will be used to serve a StepZen GraphQL API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--di8oHesm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/local-development-docker.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--di8oHesm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://stepzen.com/images/blog/local-development-docker.png" alt="Overview of running StepZen locally with Docker" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The StepZen service will run in two Docker containers, one container for the introspection service (which introspects the data sources you're connecting to) and another one that runs your GraphQL API. Also, a PostgreSQL database is used to store any metadata that is needed to run an sync your GraphQL API. The setup instructions are available in the &lt;a href="https://stepzen.com/docs/deployment/local-docker/"&gt;StepZen documentation&lt;/a&gt; and include a step-by-step guide to get you started. Including the creation of a PostgreSQL database and the installation of Docker.&lt;/p&gt;

&lt;p&gt;When you have the Docker container with StepZen running, you can use the CLI for local development in the same way as when running StepZen in the cloud. For example to import a SQL or NoSQL Database, connect to a REST / SOAP API or to use GraphQL Federation. To create a new StepZen project, please continue to the &lt;a href="https://stepzen.com/docs/quick-start/"&gt;Getting Started section&lt;/a&gt; in the documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps?
&lt;/h2&gt;

&lt;p&gt;We're always looking to improve StepZen, and continue making updates to our product. We deploy new versions of StepZen weekly, so expect new features to be added regularly.&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://twitter.com/stepzen_dev"&gt;Twitter&lt;/a&gt; or &lt;a href="https://discord.gg/9k2VdPn2FR"&gt;join our Discord community&lt;/a&gt; to stay updated about our latest developments.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
