Tutorials on Graphql

Learn about Graphql from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

How to use urql authExchange to implement authentication in Next.js

In this article, we will learn how to use the urql authExchange to add authentication with a GraphQL API in a Next.js app.In the last article , we have learnt how to use urql to execute queries and mutations in a Next.js Server-Side Rendered app. In the following sections, we will recap those learnings and build on them to implement authentication using urql exchanges. urql is a lightweight, versatile and extensible GraphQL client for modern frontend apps, with support for React, Svelte, Vue and plain JavaScript. It was introduced as an alternative to existing GraphQL clients like Relay and Apollo . Every query or mutation in urql is modeled as an 'operation', and the system at any moment has a stream of operations issued by various parts of the app. Exchanges are pieces of middleware that transform the stream of operations into a stream of results. This is explained in more detail in the architecture documentation . Some of urql 's core features such as fetching data and caching are also handled via exchanges implemented by the urql team and provided by default. You can also create your own exchanges by implementing functions that conform to the rules defined here . Next.js requires Node to be pre-installed on your system. You can then scaffold a Next.js TypeScript app using the following command in your terminal/command prompt. Once you have a skeleton app set up, you can install the dependencies required for urql . graphql is a peer dependency of urql and provides the underlying GraphQL implementation. No additional type definitions are required since urql is written in TypeScript. next-urql provides the Next.js bindings for urql . react-is is a peer dependency of next-urql , required for react-ssr-prepass to walk the component tree and pre-fetch any data required for rendering. @urql/exchange-auth provides the authExchange that we will implement our API authentication with. Finally, jwt-decode will be used to read the token and determine expiration time. We will also use Material UI to quickly scaffold out a login/register component and one that renders user info. Let us install the required dependencies for Material UI. Let us use the withUrqlClient HOC to wrap our entire app in the urql context. This makes the urql client and hooks usable in the rest of our app. The first parameter to withUrqlClient is a function that returns a ClientOptions object. This can be used to pass configuration into the urql client instance, such as the API URL, custom fetch function, request policy and any additional middleware in the exchanges property. For this tutorial, we will use the Web Collections Demo API from Formidable. In this tutorial, we will build a simple app with two screens - a login/register screen where users will authenticate or sign up to the app, and a user info screen that displays information about the logged in user. We will use the following operations from the Web Collections Demo API: We will use the browser's local storage to persist tokens across page reloads. The authExchange is a piece of middleware for the urql client, which intends to facilitate the typical JSON Web Token (JWT) based authentication flow with a simple and flexible API. It is provided in the @urql/exchange-auth package. We can add the authExchange to the exchanges property when configuring our urql client. The authExchange itself takes four pieces of configuration: The signin , register and refreshCredentials mutations from our API return an object that has the following shape. Let us implement a small helper function that stores the auth state in the browser's local storage. We've added a check for window since we only want this code to run in the browser. When the user logs out, we'd like to clear the auth state from storage. We can now add a couple of convenience functions to fetch the token and refresh token. Let us start implementing the authExchange functions, beginning with getAuth - this function needs to handle a couple of different scenarios: The addAuthToOperation function receives two parameters - the first is the current authState , and the second is the operation that will be executed next. The second parameter is of type Operation and is urql's way of representing an item in the stream of GraphQL requests. Operations have a context that contains the fetch options, either as an object or as an initializer function. We will retrieve the options for the current operation like so. We'll then create a new operation which is basically a clone of the input operation, along with our required override - the addition of our access token to the Authorization header. So the entire implementation of the addAuthToOperation function will look like this: Our API uses the GraphQL error code extension to communicate errors. For the purposes of this tutorial, we will only consider UNAUTHORIZED errors. Token expiry is one of the scenarios when we know the API will error. We are able to determine this by decoding the JWT and reading the exp field which specifies the expiration time. Our API's access token specifies the expiration time as seconds since the Unix epoch. Let us add a buffer of 5 seconds to determine that the token is about to expire. Now, this would work if all of our queries and mutations required the access token to be provided. However, we have mutations such as login and register which do not require the token passed in. We will need to adapt our logic to account for these mutations, and this can be done using the passed in Operation object. The full implementation of the willAuthError function will be as follows. Now that we have implemented all the required functions, the final step is to configure the urql client with the authExchange . Let us create a factory function that receives the ssrExchange and returns a client configuration object. We'll use this on our app's homepage in the next section. Our home page will render the login form when unauthenticated, and a user profile when the user is logged in. We'll use our clientOptions factory function here to provide the urql client to our app. We'll use two mutations login and register from the API in this component. urql 's useMutation hook can be used to consume these mutations within a React component. The useMutation hook returns a tuple containing the current state of the operation, and a function that triggers it. We'll trigger our mutations on submission of the respective form. Here is the full implementation of the page. We'll use the me query from the API to retrieve the user's ID, name and creation time. We can then use urql 's useQuery hook to execute the query. Let us create a simple layout with material-ui components to display the profile data. This will also include a loading indicator and an alert to show any error messages. In this article, we have learnt how to implement JWT authentication with a GraphQL API using urql and @urql/exhange-auth with a Next.js app. We have understood how to apply authentication to queries and mutations, and built a simple app that allows login and registration. All the code used in this article is available on my GitHub .

Thumbnail Image of Tutorial How to use urql authExchange to implement authentication in Next.js

How to Consume a GraphQL API in Next.js with urql and next-urql

In this article, we will learn how to use urql to consume a GraphQL API in a Next.js SSR app.urql is a lightweight, versatile and extensible GraphQL client for modern frontend apps, with support for React, Svelte, Vue and plain JavaScript. It was introduced as an alternative to existing GraphQL clients like Relay and Apollo . These GraphQL clients are largely similar when it comes to setup and use. In the next section, we will see how they compare with each other on various parameters. All three GraphQL clients provide standard features such as queries, mutations, caching and subscriptions, while only differing slightly in implementation. urql 's defaults for configuration are slightly better than those for Apollo, and it has a lower entry barrier thanks to its thorough documentation and native support for features otherwise only available via third-party plugins. Additionally, urql has a powerful caching mechanism offers both normalized and document caching via the @urql/exchange-graphcache package. urql is built on the principle of having a lightweight core, extensible via middleware called exchanges. This makes it the smallest in bundle size as compared to the other options. A full, detailed comparison of the clients by different categories of features can be found on the urql website . Next.js is one of the most popular React-based frameworks, and urql has first class native support for it via the next-urql package. Apollo and Relay do not have official plugins with support for Next.js which means the implementation might change between releases of the framework, and any app that uses it will have to be constantly maintained to keep up. With next-urql , most of the boilerplate involved in setting up urql for Server-Side Rendering (SSR) with Next.js is already done for you. It provides convenience functions such as the withUrqlClient HOC which enables your SSR pages to pre-fetch data via GraphQL queries. Next.js requires Node to be pre-installed on your system. You can then scaffold a Next.js TypeScript app using the following command in your terminal/command prompt. Once you have a skeleton app set up, you can install the dependencies required for urql . graphql is a peer dependency of urql and provides the underlying GraphQL implementation. No additional type definitions are required since urql is written in TypeScript. next-urql provides the Next.js bindings for urql . react-is is a peer dependency of next-urql , required for react-ssr-prepass to walk the component tree and pre-fetch any data required for rendering. We can use the withUrqlClient HOC to wrap our entire app in the urql context. This makes the urql client and hooks usable in the rest of our app. The first parameter to withUrqlClient is a function that returns a ClientOptions object. This can be used to pass configuration into the urql client instance, such as the API URL, custom fetch function, request policy and any additional middleware in the exchanges property. For this tutorial, we will use the GitHub GraphQL API. This API requires you to authenticate using a personal access token. You can follow the steps described here to create one after logging in with your GitHub account. We can then configure our urql client to pass the token as part of the authorization header on each request to the API. Now that we have our urql client set up, let us look at how we can use it to connect to the GitHub API and fetch some data. We will build a simple component that will display a list of repositories, with each item showing a link to the repo, its name, star count and commit count. The component will look somewhat like this. To start, let us look at the GraphQL query that should be used. This query fetches the first 10 repositories for the current user (determined from the personal access token). For each repository, it includes the name, ID, URL, stargazer count and the number of commits to the main branch. There are various other fields that can be added to the query, as documented in the API reference . We can execute this query using the useQuery hook from urql . Since we're using TypeScript, let us model the API response with the correct expected types and use them as type parameters to useQuery . The response object returned by useQuery returns a number of useful items, out of which we will currently use the fetching flag which tells us whether or not the operation is still in progress, and the data property which contains the fetched data when available. Let us now add some simple UI to render the returned data. This Repositories component now fetches and renders a list of repositories with star and commit counts. So far, we've seen how to set up urql in a Next.js app and use it to query the GitHub GraphQL API. Let's now take it a step further and learn how to create mutations - these are API operations that can cause the data to change in the backend. For the purposes of this tutorial, we will implement the creation of an issue within a given GitHub repository. The GraphQL mutation to create an issue looks like this: This mutation takes three variables - the repository ID to create the issue in, the title and the body of the issue. On success, it returns an Issue object that can contain the number, title and body. So let us model the request variables and response, and create the mutation. The useMutation hook returns a tuple with two items - an object that exposes the current state of the mutation request, and a function that can be invoked with input variables to execute the actual mutation. Let us adapt our Repositories component to be able to call this mutation. We'll refactor and extract some of the code into an individual Repository component along the way. This is what the refactored Repositories component will look like. All the GraphQL types have been moved to a separate types module. And the individual Repository component now renders the list item, along with a button that invokes the createIssue mutation when clicked. Clicking the button creates an issue with a sample fixed title and body in the corresponding repo. Every query or mutation in urql is modeled as an 'operation', and the system at any moment has a stream of operations issued by various parts of the app. Exchanges are pieces of middleware that transform the stream of operations into a stream of results. This is explained in more detail in the architecture documentation . Some of urql 's core features such as fetching data and caching are also handled via exchanges implemented by the urql team and provided by default. You can also create your own exchanges by implementing functions that conform to the rules defined here . Server-Side Rendered apps need to be set up to fetch data on the server-side and send it down to the client for hydration.  urql  supports this via the ssrExchange . The SSR exchange has two functions - it gathers all the data as it is being fetched server-side, and using the serialized data on the client side to rehydrate the app without a refetch. When using next-urql , most of the boilerplate involved in instantiating the ssrExchange is already done for you. So if your client does not use any other exchanges, you do not explicitly need to instantiate the ssrExchange when creating the client. To enable SSR, you simply need to set the ssr flag in the second argument to the client configuration function. If you do want to add other exchanges to your client, they can be specified in an exchanges property returned by the configuration function. This function also gets the instance of the ssrExchange passed into it when called. Enabling SSR when wrapping the top level App component in withUrqlClient disables Next's ' Automatic Static Optimization ' which allows for hybrid apps with both server-side rendered and statically generated pages. If this is required in your app, you can wrap individual page components with withUrqlClient as required. When applying withUrqlClient to specific pages, we can also use getStaticProps or getServerSideProps to pre-fetch the data and populate the urql cache. This will render the page as a static page, further optimizing performance and allowing us to perform other operations in these functions. Let us adapt our app to use server-side rendering with getServerSideProps for our repositories component. We will add getServerSideProps to our Home page component, as this function can only be exported from page components. The getServerSideProps function gets called when the page is being rendered server-side. It will populate the cache so that the subsequent render of the Repositories component will hydrate it from cache when useQuery is called. In this article, we have learnt how to set up urql with a Next.js app and perform queries and mutations against the GitHub GraphQL API. Further, we have also learnt about the architecture of urql and how Exchanges work. We have used next-urql to implement server side rendering with pre-fetching of queries using the urql client and cache. In a subsequent tutorial, we will learn how to use urql exchanges for authentication and caching. All the code used in this article is available on my GitHub .

Thumbnail Image of Tutorial How to Consume a GraphQL API in Next.js with urql and next-urql

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

Should I Directly Access Data From the Apollo Client or From React Component State?

Consider the following code snippet of a React component, <App /> , that... You may have noticed that the data sent back by the mutation provides the user's information in a logIn field, and any data returned from a successful mutation automatically gets added to the local Apollo Client cache. Therefore, why do we have a user state variable when we could just access the user's information via the data field in the mutation result object? For example, like this: This can be considered an anti-pattern, but data can be either undefined or { logIn: { id: ..., token: ..., ... } } . Therefore, you would need to check if data is undefined or not directly in the body (and rendering section) of the <App /> component. Even after you determine that data is not undefined , you would still need to perform the same number of checks as before for the logIn property, etc. By using the setUser approach, you start with a baseline user object with its properties initialized to null , so you don't have to check if the user is undefined in the body (and rendering section) of the <App /> component (one less check). Additionally, with this approach, you only perform the checks for the data inside the onCompleted function. You could directly access the cache via the update function, which is called after the mutation completes and provides the cache as an argument, like so: However, the cache at this point doesn't actually have user data in the cache (to confirm this, print JSON.stringify(cache.data.data) in the update function). The user data is provided separately as the update function's second argument. You would need to manually modify the cache so that it has this user . Once the cached data is updated, the change gets broadcasted across the application and re-renders the components with active queries that correspond to the updated data. So you would need to put into each component that relies on user a call to useQuery that fetches the user . On initial page load, it's an extra, unnecessary network request since the LOG_IN already gets us the user data. But after the initial page load, if the user decides to log in or log out, then getting the user will be based on the update to the cache and having its updated user data be broadcasted to the useQuery s. In this case, it's more ideal to use setUser if it means one less network request on initial page load. As always, it's completely up to you how you want to manage state in your applications, but be sure to evaluate the trade-offs for each possible solution and pick the one that best suits your situation. Check out this Codesandbox example to see what I mean: https://codesandbox.io/embed/mutations-example-app-final-tjoje?fontsize=14&hidenavigation=1&theme=dark If you want to learn more advanced techniques with TypeScript, GraphQL and React, or learn how to build a production-ready Airbnb-like application from scratch, then check out our TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL :

Thumbnail Image of Tutorial Should I Directly Access Data From the Apollo Client or From React Component State?

Fullstack React with TypeScript Masterclass is LIVE 🎉

The Fullstack React with TypeScript Masterclass is now live! 🎉   This Masterclass teaches you practical React and TypeScript for developing apps from idea to completion, along with all the important tools in the React ecosystem. It expands on the material taught in our comprehensive book,  Fullstack React with TypeScript , and gives you over 10 hours of video lessons taught by Maksim Ivanov. By the end of the first module, you'll already have created your environment for React with TypeScript, and you will have completed basic tasks with TypeScript. The subsequent modules then continue your journey through building multiple apps and learning techniques including: This masterclass was developed by Maksim Ivanov and Alex Bespoyasov and taught by Maksim. Maksim worked for leading game developer Mojang, where he helped develop front-end interfaces with React and TypeScript. He has continued his front-end work at Spotify, where he develops interfaces with React, TypeScript, and related tools.  Alex is a frontend developer and works with technology company 0+X where he consults on developing and maintaining applications with React and related tooling.  With their combined depth of expertise, Maksim and Alex will quickly get you up to speed on creating modern React and TypeScript apps that your users will love. You can read more details about the Masterclass over at the Fullstack React with TypeScript Masterclass page .

Thumbnail Image of Tutorial Fullstack React with TypeScript Masterclass is LIVE 🎉

Picking a GraphQL Client

There are a bunch of GraphQL clients that exist. How do you know which one is right for you? I'm going to discuss some of your options, but let's cut to the chase: If you're building a front-end web-app, I recommend you use Apollo Client. If you want to take my recommendation, you can just skip this and move on with your life. But. For those of you who are making a years-long, fundamental architectural decision for your team - you might want to read below to better understand the tradeoffs between a few of the popular GraphQL client libraries. Because GraphQL servers are typically over HTTP, you don't have to use a client library at all. You can just use whatever HTTP request library you were already using and it will "work". GraphQL is in this sense, more of a language/protocol pair than a specific library and it will work fine in any language where you can form queries and parse JSON - making it suitable for mobile apps, compiled clients, etc. You can query a GraphQL server using curl , The operationName here is the name of your query. With curl, it would look like this: where the ... is replaced by the JSON string from above So why bother with a dedicated client? The big reason is because of caching . Because our data is typed, and has a specific schema, intelligent clients can leverage that to cache data in clever, optimized ways. For example, an object that is loaded by one query may already have been cached by a previous, completely different query. And in these cases, the client can read from the cache instead of fetching from the server - resulting in a snappier user experience. There are lots of other nice features a dedicated client might have, too. Such as: All of the above can add up to a real-world advantage in programming time compared to just forming manual HTTP requests every time. So if you want to use a dedicated client, what are your options? Here's a few: Let's look a little closer at each one: graphql-request is a JavaScript library that, as it's namesake, makes it easy to make GraphQL requests. Here's what the code looks like, taken straight from the documentation What's good: The drawbacks: It is super minimal - it doesn't have any caching or most of the advanced features you'd get out of any of the clients below. Summary: It's a great fit if you just want to make some quick requests without a lot of fuss. urql gives you solid, lightweight choices in the default configuration, but is build to expand as you grow. They have a nice page on the philosophy of urql where they say: Here's an example of making a query in a React app, taken from their documentation : Above, you can see that they call the useQuery hook to load the TodosQuery and then use that result in the rendered JSX. What's good: The drawbacks: Summary: A solid library, with critical community mass, from a great team. It's a good option. Relay Modern a full-featured GraphQL client library and the original inspiration for Apollo. What's good: What's good: The drawbacks: Summary: An inspirational, tightly-React-integrated library with many good characteristics, but generally not used as widely as you'd expect. I imagine that Relay Modern will ship a version that gets broader community adoption. Almost everyone I know in the industry that would use Relay is using Apollo instead. But if you're new to GraphQL and you're trying to decide between Relay and Apollo, and you don't know the difference, 9-times-out-of-10 you want Apollo. Like I mentioned above, Apollo Client today's de-facto standard GraphQL library - works w/ React, Angular, Vue, etc. What's good: The drawbacks: It's relatively "heavy". If you run into trouble, it's a bit of a black box. Summary: I use Apollo for newline and I've been incredibly happy. As often happens in open-source, there's ecosystem benefits with going with the leader. There are more tutorials, bugs are fixed faster, and it's an overall pleasant experience. Apollo also has tooling for building servers, so it's a bit of a one-stop-shop for GraphQL services. It's pretty obvious that I'm an Apollo fan. While there might be better choices for certain scenarios, if you're building a straightforward web app, my recommendation is Apollo client. Hope this helps! -- Nate

Building a GraphQL Application with Vue 3 and Apollo

RESTful APIs adhere to a reliable architectural standard for transferring data statelessly over the HTTP protocol. Every endpoint of an API semantically describes how a resource should be created ( POST ), read ( GET ), updated ( PUT / PATCH ), deleted ( DELETE ), etc. Large, data-driven applications consume data from multiple third-party/in-house sources, and each one exposes a unique set of endpoints to manage different resources. Adapting these applications to support a wide range of platforms and device sizes (commonly mobile, desktop and web) may present several problems: Using Facebook's GraphQL query language, the client specifies its exact data requirements to the server via a single endpoint. Establishing a schema (written with the syntax of the GraphQL Schema Definition Language) creates a contract between the client and server that defines what data can be read from and written to the data graph by the client. This data graph centralizes all of the APIs consumed by your application by mapping each field to a resolver that populates it with a value retrieved from an endpoint of one of these APIs, a database, etc. A client can fetch data from a GraphQL server via plain HTTP and then manually update the UI accordingly. However, GraphQL clients such as Apollo Client abstract away the low-level implementation details of these features underneath a declarative API. Built by the Apollo GraphQL team, Apollo Client is an open-source GraphQL client that provides a lot of out-of-the-box functionality for communicating with a GraphQL server: To integrate Apollo Client into an application using another JavaScript library/framework besides React, which Apollo Client already has built-in support for, there exists view integration libraries within the Apollo ecosystem that provide bindings for Vue , Svelte , Angular , Ember and Web Components . The Vue Apollo library integrates Apollo Client into a Vue application. Different versions of Vue Apollo are compatible with different versions of Vue: Although Vue Apollo v4 is still in active development (alpha phase), it offers support for Vue 3's Composition API , which collocates the methods corresponding to component options ( watch , computed , etc.) and lifecycle hook registrations ( onMounted , onUnmounted , etc.) within a single component option, setup . Using Vue Apollo v4 methods, such as useQuery and useMutation , the data requirements are also placed within the setup method. This approach makes it much easier to reason about a component's code compared to the Vue Apollo Options API approach, which places the data requirements within an apollo component option (independent of the other code placed within the remaining component options). Below, I'm going to show you: Using Vue 3's Composition API and the Vue Apollo (v4) library, we will be building the following GitHub search client: To start, download this project from GitHub: This repository is based on a custom Vue CLI project template that runs Vue 3 and includes support for TypeScript, ESLint and Prettier. If you want to learn how to manually set up the base structure of this project, then proceed to the next section (" Installation "). Otherwise, you may skip the " Installation " section, download the already prepared project structure and proceed directly to the " GitHub GraphQL API " section. To generate a new Vue CLI project, run the following command in the terminal: When prompted with "Please pick a preset," select the "Manually select features" option: This project will support TypeScript. Press "Space" to select "TypeScript." When prompted with "Choose a version of Vue.js that you want to start the project with," select the "3.x (Preview)" option: Vue components will not be written with the class syntax. The Class API was officially dropped . This project will use Babel alongside TypeScript. For linting and code formatting, select the "ESLint + Prettier" option: Anytime changes to a file are saved, run the linter. For this project, let's place the Babel, ESLint, etc. configurations within their own dedicated files to avoid increasing the size of package.json . These answers are only for this project. In the future, you may want to try out different sets of project configurations to determine what specific tools make you more productive. To integrate type definitions from the schema of GitHub's GraphQL API , install @octokit/graphql-schema : Several type definitions are assigned nullable types , which will cause ESLint to raise the following error within your IDE. Inside of the .eslintrc.js file, turn off the rule @typescript-eslint/no-non-null-assertion . ( .eslintrc.js ) In 2017, GitHub publicly released its GraphQL API . GitHub's GraphQL API exposes a public schema for interacting with GitHub itself, whether fetching commit data or starring a repository, all accessible from a single endpoint. To send requests to GitHub's GraphQL API, generate an access token. This access token must be set to each request's Authorization header. When setting permissions for the access token, enable repository privileges. Create a .env file at the root of the project directory. Copy the 40 character-long access token to your clipboard. Set the environment variable VUE_APP_GITHUB_ACCESS_TOKEN to this access token. ( .env ) Note : Environment variables prefixed with VUE_APP_ can be accessed via process.env within Vue applications. Without this prefix, environment variables are undefined . First, install graphql , @apollo/client and @vue/apollo-composable as dependencies: To rapidly style the UI interface, we will be using the Tailwind CSS framework. Install tailwindcss , postcss and autoprefixer as dependencies: Then, create a minimal Tailwind configuration file ( tailwind.config.js ) at the root of the project directory. Note : The -p flag creates a minimal PostCSS configuration file ( postcss.config.js ) at the root of the project directory, alongside the generated tailwind.config.js . Inside of tailwind.config.js , set the purge option to a list of filenames/globs for PurgeCSS to analyze and remove unused CSS. ( tailwind.config.js ) Inside of public/index.html , add these two CSS classes to the <body /> element: ( public/index.html ) When you run the application, you will encounter the following error: Although the latest version of the tailwindcss PostCSS plugin (v2) is compatible with latest version PostCSS (v8), other tools within the PostCSS ecosystem may not yet be compatible with this version of PostCSS. To resolve this error, uninstall tailwindcss , postcss and autoprefixer , and then reinstall these dependencies with the PostCSS (v7) compatibility build. Inside of main.ts (the entry point of the Vue 3 application), create an ApolloClient instance. Let's pass an object containing configuration options to the Apollo Client: For this application, we will define two links: To inject the Apollo Client into the application and allow child components to access the Apollo Client, call the provide method within the createApp 's setup method to "provide" this client to the application and its children components. Since this application only interacts with a single GraphQL API, set this client as the default client. Putting it altogether... ( main.ts ) Our application requires three child components: By default, the reactive searchOptions object, which represents the arguments passed to the GitHub GraphQL API's search query, is dynamically assigned to the prop search-options of the <RepositoryList /> component. Any changes to searchOptions , particularly to query , which corresponds to the value of the search bar's input, will cause the <RepositoryList /> component to retrieve a new list of repositories. The value of query is changed whenever the search event is emitted from the <SearchBar /> component, which occurs on changes to the value of its input. ( src/App.vue ) Typing a query emits a "search" event with the current query and triggers the search function in the <App /> component. This search function sets the value of the query field in the reactive searchOptions object. Debounce the handleInputChange event handler to avoid sending the search event on every single input change. ( src/components/SearchBar.vue ) When an event is fired, this debounce function starts a timer and waits for a specific time period to elapse before calling its corresponding event handler. If another event is fired during this time period, then the previous event is ignored. The timer resets and must wait for the specific time period (now reset) to elapse before calling the new event's corresponding event handler. This debounce function invokes the event handler on the trailing edge of the timeout. ( src/utils.ts ) Store the queries and mutations within a single file. This application requires only one query and two mutations: If you decide to add more queries/mutations that return a repository/repositories, and you request for the same repository fields for those queries/mutations, then use the repo fragment to keep your code DRY. ( src/graphql/documents.ts ) Inside of the <RepositoryList /> component, fetch a list of repositories based on the searchOptions passed from the <App /> parent component. To fetch this list of repositories, the component executes the composition function useQuery , which accepts a GraphQL document ( SEARCH_REPOS ) as the first argument and query arguments ( searchOptions ) as the second argument. This function is compatible with the setup function of Vue 3's Composition API. useQuery returns an object that contains several Ref values: Sometimes, a query may return multiple top-level objects. To pick a single object from the result object returned by useQuery , use the useResult composition function. Instead of referencing the repositories from the result object as result.search.edges in the component's template, it can just be referenced as repositories . Plus, the default value assigned to repositories is the second argument passed to useResult (in this case, an empty array). ( src/components/RepositoryList.vue ) Inside of the <Repository /> component, there is a button for starring/unstarring a repository, depending on whether or not you have starred the repository previously. If you have not yet starred the repository, then clicking the button will star the repository, and vice-versa. The event handler calls either the unstarRepo or starRepo functions to unstar or star a repository respectively. Each of these functions execute the composition function useMutation , which accepts a GraphQL document ( ADD_STAR or REMOVE_STAR ) as the first argument and options (an object containing mutation arguments via the variables property, etc.) as the second argument. Similar to useQuery , this function is compatible with the setup function of Vue 3's Composition API. When a repository is starred/unstarred, we must update the cache to reflect this mutation. To understand why this is important, let's walkthrough an example. Imagine you typed the query "facebook" into the search bar's input. This will fetch all repositories relevant to "facebook" from GitHub's GraphQL API. Suppose you have already starred the facebook/react repository, and you decide to unstar it. After you unstar it, you decide to type the query "google" into the search bar's input. This will fetch all repositories relevant to "google" from GitHub's GraphQL API. If you again type the query "facebook" into the search bar's input, then this will fetch all repositories relevant to "facebook" from the Apollo Client's cache . What was cached previously for this query was a list of repositories relevant to "facebook," including the facebook/react repository. However, this repository was cached when it was still starred. Therefore, we must modify this repository in the cache to reflect that it was recently unstarred. To update the cache, set the update property in the options object to a function that provides an instance of the cache and the data returned from a mutation. This function will call the overrideMutationStarCache , which will read the already cached data (via the cache 's readQuery method) and write the result of the mutation to the appropriate repository entity (via the cache 's writeQuery method). Don't forget to also increment/decrement the stargazers count! Putting it altogether... ( src/components/Repository.vue ) Run the application locally: Visit localhost:8080 in a browser to interact with the application. In this blog post, we only explored a very small subset of the GitHub GraphQL API. Try experimenting with other aspects of the public schema of the GitHub GraphQL API. For a more difficult challenge, try connecting an existing Vue 3 application to a custom GraphQL server. If you want to learn more about Vue 3, then check out Fullstack Vue :

Thumbnail Image of Tutorial Building a GraphQL Application with Vue 3 and Apollo

Generate TypeScript Types from GraphQL

In this post, I want to explain something that tripped me up for a long time: how to generate TypeScript types from a GraphQL server. They are! In fact, you even have types for your queries , which is extra confusing. Let me try to clarify. So, in your GraphQL server you might expose a User object. User has fields like id , email , username , profileImageUrl etc. When your client consumes this API it is over HTTP -- but if we're using TypeScript, it would be nice to have TypeScript types that match the GraphQL types. So again, *and they both have their own, separate, types . This post shows you how to generate TypeScript types from your GraphQL server. And it's super handy because not only is your code type-checked, but your editor will also help you autocomplete. At first, you might try writing these types by hand, but this will just drive you crazy to maintain by hand as your app grows. However, in a large scale production application, there could be hundreds of GraphQL endpoints & types. Take a look at GitHub's v4 GraphQL API , no joke, there are almost 1,000 endpoints & types. Creating TypeScript definitions for those (by hand) would be a nightmare! Not only that, a change in the server means you will have to find and update your TypeScript definitions over and over again. Ew. Of course every GraphQL API already has types defined in the schema. Wouldn't be great if there is something that can translate GraphQL types into TypeScript automatically? As you've probably predicted, there is. Ladies & gentleman, let me introduce to you, Apollo CLI . The Apollo CLI is a robust command line interface that allows for a variety of different things such as schema validation, generate static types, and etc. And we'll use this tool to auto-generate TypeScript definitions from our GraphQL API. Here's how: To use the Apollo CLI, we can install it globally with the following command: There are two commands we are especially interested in: We'll set up both of these steps as two separate script commands in our application's package.json file. We'll label these scripts codegen:schema and codegen:generate . To download the schema, we'll need to run the apollo client:download-schema command and specify the options we would want. In our case, we'll specify the single minimum option we need - the endpoint and pass in the value of our local GraphQL endpoint ( http://localhost:9000/api ). We'll run the newly created codegen:schema script in our command line. After a brief period, we'll notice success messages that state Loading Apollo Project and Saving schema to schema.json . If we look at the root of our client/ directory, we'll notice a schema.json file be generated that represents our entire GraphQL schema! With the GraphQL schema available in our app, we can now look to generate the static types for the listings query and deleteListing mutation in our GraphQL API. This can be done with the Apollo CLI client:codegen command. We'll specify a few options as we set up the script. The first option we'll add is the --localSchemaFile option, which is used to specify the path to the schema file in our client/ directory. Since the schema.json file is in the root of our project, the value for the --localSchemaFile option will be schema.json . The second option we'll specify is the --includes option which is used to state the files that contain the GraphQL operations we'll want to generate static types for. In my case, all of my GraphQL requests live in TypeScript files within my src/ folder. There fore, I'll specify a value of src/**/*.tsx which entails looking through our entire src/ folder and for any files that have the .tsx file extension. The final option we'll specify is the —-target option, which is required and allows us to specify which code generator we'd like to use. swift , flow , scala are all different options but in our case we're interested in the typescript option. We'll have the above apollo command as part of the codegen:generate script command in our application. We can now run the newly created codegen:generate command in our terminal. Upon success, we'll see the Loading Apollo Project message followed by Generating query files with 'typescript' target - wrote 3 files . By default, the Apollo code generator creates static typings for the GraphQL documents it finds in __generated__/ folders. For example: If we take a look at one of these auto generated files, we can see TypeScript interfaces for the return data and input variables! In Tinyhouse, you'll get up to speed with this whole stack really quickly. We've organized the course so that you can skip around if you just want to learn a specific part, but we also build the whole production-ready app if you want to walk through step-by-step. Check out Tinyhouse: a Fullstack React Masterclass

Thumbnail Image of Tutorial Generate TypeScript Types from GraphQL

Getting Started with GraphQL in React using Apollo Client

Apollo is a great interface for fetching and managing data through GraphQL. When we’re building applications with GraphQL, it’s important to manage data effectively to have a smooth development experience. This is where Apollo steps in, and acts as an abstraction layer over GraphQL (which is just a query language) , and provides a robust platform for data fetching. The power of Apollo lies with how much we get out of the box (it’s a lot). We don’t need to do lengthy custom setups or configurations and can get started right away. Here, we’ll be discussing the benefits and usage of Apollo Client with ReactJS, but it’s important to note that most of the same features are also available in Angular and Vue. Before we dive deeper into Apollo, let’s briefly discuss GraphQL. GraphQL is a query language, built by developers at Facebook that emphasizes predictable results by building schemas for building queries. We use a tree structure to fetch data through a single central API endpoint. With traditional REST APIs, we are usually exposing multiple APIs for different purposes. For example, we might have an API to fetch books, and a different API to fetch authors. Similarly, we may have APIs to get a singular book or author. With GraphQL, we only hit a single endpoint, but we use fields to fetch only the data we need, such as only the name of the book, in a sea of different available parameters made available by the back-end. By making a single request, our application can be fast even on slow mobile networks. The type system of GraphQL keeps the API structure robust, and the dev tools help us see the schema definitions to easily debug our requests. Moreover, it solves the problem of over-fetching and under-fetching, as we’re able to get exactly the data we need in one hit. Its optimistic UI and caching make all interaction with the server super fast and snappy. On the server-side, we import the required libraries and create schemas for Queries and Mutations, respectively. This prevents us from spending time thinking of complex API flows. Queries are used to read data, whereas Mutations are used to create, update, or delete the data. Here is a very basic example from the GraphQL documentation: First, we build the schema where all our possible queries lie, Now, we can create a root resolver that hosts all our functions corresponding to the queries we have created: Finally, we can initialize our application with GraphQL. The algorithm itself is very simple, it resolves each field before diving inside and doing the same until all the fields are resolved. After that, the result is returned in the required format. To describe and initiate our queries on the front-end, we can