Author: Kellen Mace

  • GraphQL Code Generator for WPGraphQL

    When getting started with TypeScript, developers quickly become accustomed to defining their typings. For a React component that’s responsible for rendering a single blog post’s content, you may write something like this:

    type Avatar = {
      url: string;
    };
    
    type User = {
      name: string;
      avatar: Avatar;
    };
    
    type Post = {
      databaseId: number;
      title: string;
      slug: string;
      excerpt: string;
      content: string;
      author: {
        node: User;
      }
    };
    
    type Props = {
      post: Post;
    };
    
    export default function BlogPost(props: Props) {
      const { post } = props;
      return (
        

    {post.title}

    {/* etc. */}
    ); }

    You can see that the BlogPost component accepts an argument with a type of Props, which itself uses a type of Post. Post uses the User type, which in turn uses the Avatar type. Sure, you may be able to nest some of those types inside others to make things a bit more concise, but you still end up with quite a few type definitions. While this code works fine, you may find that it is time-consuming to create all the types for your project manually.

    If your project sources its data from a GraphQL API, you may look at the GraphQL schema and think:

    “Wait…since my GraphQL schema is strongly typed, can’t I just leverage those same types in my TypeScript code instead of reinventing the wheel?”

    You, my astute friend, are in luck! That is indeed possible using GraphQL Code Generator, a.k.a. “GraphQL Codegen.” This free, open-source tool can use your GraphQL schema to generate TypeScript typings. This image sums it up nicely:

    Set Up

    Let’s learn how you set up GraphQL Codegen in your headless WordPress projects that use WPGraphQL.

    Enable GraphQL Introspection

    In the WordPress admin sidebar of your local environment, head to GraphQL > Settings. Make sure the Enable Public Introspection option is checked. This will allow GraphQL Code Generator to run an introspection query against your GraphQL endpoint to get the entire schema.

    Initialize GraphQL Code Generator

    1. Head over to the GraphQL Code Generator Getting Started documentation page. Follow the steps for installing the graphql and @graphql-codegen/cli NPM packages.
    2. Run npx graphql-codegen init (or yarn graphql-codegen init) to launch the initialization wizard. Below, we’ll cover what to enter for each prompt.

    What type of application are you building?

    Select Angular/React/any thing your heart desires.

    Where is your schema?

    Paste in your local WordPress site’s GraphQL endpoint. You can see it on the WPGraphQL settings page here:

    Where are your operations and fragments?

    Enter the path to where the .graphql files containing operations and fragments. Example: src/**/*.graphql. If you don’t have .graphql files in your project, just hit enter to go to the next step.

    Pick plugins

    Make sure to check TypeScript (required by other typescript plugins. Look if TypeScript Operations (operations and fragments) only if you have .graphql files containing GraphQL operations and fragments in your project; un-check it, if not. Leave all other options unchecked and hit enter to continue.

    Where to write the output

    Enter generated/graphql.ts. This tells GraphQL Code Generator what file it should write the generated typings.

    Do you want to generate an introspection file?

    Choose “No”.

    How to name the config file?

    Hit enter to accept the default codegen.yml filename.

    What script in package.json should run the codegen?

    Enter generate.

    The GraphQL Codegen CLI will:

    • Generate a codegen.yml configuration file based on your answers
    • Add a few NPM packages to your devDependencies to your project
    • Add a new generate script in package.json. You’ll be able to run whenever you want to generate your typings

    The command line output should look something like this:

    Next, run npm install (or yarn) to install the new devDependencies.

    If you do not have .graphql files containing GraphQL operations and fragments in your project, remove the entire documents: line from codegen.yml and save the file. If you don’t do this, GraphQL Codegen will throw an error when you try to generate your typings since it will be unable to find those files.

    Generate Your Typings

    With typing set up complete , run npm run generate to generate your typings. GraphQL Code Generator will access the GraphQL schema via your local site’s GraphQL endpoint and generate TypeScript typings.

    Congrats! You have now used your GraphQL schema to generate TypeScript typings you can use in your frontend app! You can check out the generated/graphql.ts file to see all the generated typings.

    How to Use the Generated Types

    Let’s revisit our BlogPost component example from the beginning of this blog post. Rather than all of those type definitions we had created manually, we can instead do this:

    import { Post } from "../../generated/graphql";
    
    type Props = {
      post: Post;
    };
    
    export default function BlogPost(props: Props) {
      const { post } = props;
      return (
        

    {post.title}

    {/* etc. */}
    ); }

    You can see that this is quite a bit simpler. Rather than creating our typings manually, we can leverage the ones that GraphQL Codegen generated for us.

    When to Generate Typings

    You can commit the generated/graphql.ts to your version control system so the generated types are stored alongside the rest of your project. Anytime you want to regenerate the types (such as if you make changes to the GraphQL schema or install a WPGraphQL extension), you can run npm run generate again. This will overwrite your current generated/graphql.ts file.

    Plugins & Integrations

    We’ve learned the basics of how to set up and run GraphQL Code Generator to generate typings using our GraphQL schema. If you want to go further and automatically generate even more code for your project, I encourage you to check out the GraphQL Code Generator plugins available.

    There are plugins available for Apollo Client, React Query, GraphQL Request. and other popular libraries that generate other things for you, such as custom React hooks, higher-order components, etc.

    Note for Gatsby users: an integration also exists to generate typings from Gatsby’s unified GraphQL data layer. See the documentation for details.

    Wrapping Up

    I hope this post is helps you understand the benefits you can gain by using GraphQL Code Generator to generate typings for your frontend JavaScript app based on your GraphQL schema. You should also have a good idea of how to set up GraphQL Codegen for your projects and run it to generate your types. Thanks for reading!

  • Build an App Using React and the GraphQL Plugin for WordPress in ~15mins

    If you keep up with tech trends, you likely already know that GraphQL is one of the newer breakout technologies that people are gushing about. It’s an open source specification created and used by Facebook’s Engineering team that can be used to push and pull data between APIs and apps. REST APIs have traditionally been used for that purpose, but GraphQL has several advantages over them that you can read more about here.

    If you work on the WordPress platform, you’ll be happy to learn that a GraphQL implementation exists for WordPress – the WPGraphQL plugin! The project was started by Jason Bahl and is being actively being developed by him and a number of other contributors. In this post, I’ll walk you through building a sample app that uses React and Apollo Client in the browser to fetch data from a WordPress site that’s running WPGraphQL. Let’s roll! ????????

    Building Our App

    We’re going to build an app that allows you to search for blog posts. If any matches are found on the server, WPGraphQL will send back the data we requested for each post and our React app will render cards to the page for the matching posts. Here it is in action:

    The completed app is available in the WPGraphQL Examples repo.

    In order to use GraphQL, you need software running on the server to receive requests, process them then send back a response. Server implementations exist in most popular server-side languages (PHP/Node/Python/etc.). We’ll be using the WPGraphQL plugin on the server, which takes two existing PHP libraries for GraphQL (graphql-php & graphql-relay-php), and layers WordPress-specific functionality on top of them, so that it’s possible to run queries for blog posts, pages, taxonomies, settings, users, and many other WordPress-y things (these are referred to as “types” in GraphQL parlance).

    Once the server supports GraphQL, you’ll also need a client-side library to help out with sending the requests to the server and receiving the responses that come back. Many such libraries exist. For our client-side app, we’ll be using Apollo Client.

    Steps to Follow

    1. Make sure you have node and npm installed and are mildly familiar with React and running commands on the command line.

    2. Install and activate the WPGraphQL plugin on the WP site you’d like to pull data from. You should then be able to visit the /graphql endpont in a browser, such as example.com/graphql and see JSON output rather than your site’s 404 page. Don’t worry if you see a “Syntax Error GraphQL” message in the JSON output. That’s expected, since we haven’t sent a valid request to the /graphql endpont yet – merely visited it directly in a browser.

    One important distinction to note here: with REST APIs, many different endpoints are used, depending on the type of data you need to send/receive. With GraphQL though, all requests use a single endpoint. The WPGraphQL plugin registers the /graphql route for that purpose.

    3. Run these commands to get a fresh app up and running locally using Create React App:
    npx create-react-app using-react-apollo
    cd using-react-apollo
    npm start

    You can now open http://localhost:3000/ to see your app. You can hit ctrl+c whenever you need to stop it, then npm start whenever you need to get it running again.

    4. Install the npm packages we need.
    npm install apollo-boost react-apollo graphql graphql-tag

    Here’s a brief description of each:

    • apollo-boost: Package containing everything we need to set up Apollo Client
    • react-apollo: Apollo Client view layer integration for React
    • graphql: Library for parsing GraphQL queries
    • graphql-tag: Library that takes ES6 template literal strings and compiles them into GraphQL ASTs (Abstract Syntax Trees) that can then be passed into Apollo Client

    5. Open the project in a code editor. In the /src/ folder of your project, delete all the files except index.js and index.css to clean things up a bit.

    6. Replace the contents of /src/index.js with the code below, but swap out “https://content.wpgraphql.com/graphql” with the URL of the WP site you want to pull data from.

    import React from 'react';
    
    // Helper function for formatting dates.
    const formatDate = date => new Date( date ).toDateString();
    
    const PostCard = ({post}) => {
      const { postId, title, date, author, featuredImage } = post;
      const { name: authorName } = author;
    
      return (
        
    { featuredImage && // If a featured image exists, display it. {featuredImage.altText} }

    {title}

    Date: {formatDate(date)} Author: {authorName}
    ); }; export default PostCard;

    You can see that we’re creating a new client using Apollo and providing it with the URL endpoint to use for GraphQL requests. We’re also wrapping our entire app in a new ApolloProvider and passing to it the client we created as the client prop. The result of this is that we’ll now be able to use the react-apollo library to make GraphQL requests anywhere inside of our app.

    7. Replace the contents of /src/index.css with this code to give our app some style. ????

    8. You may have noticed that /src/index.js tries to import a PostsSearch component that doesn’t exist yet. Let’s fix that! Create a new /src/PostsSearch.js file and paste in this code:

    import React, { Component } from 'react';
    import PostsList from './PostsList';
    
    class PostsSearch extends Component {
      state = {
        searchQuery: ''
      }
    
      handleSubmit = event => event.preventDefault();
    
      handleInputChange = event => {
        const { name, value } = event.target;
        this.setState({ [name]: value });
      };
    
      render() {
        const { state, handleSubmit, handleInputChange } = this;
        const { searchQuery } = state;
    
        return (
          
    {searchQuery &&
    }
    ); } } export default PostsSearch;

    This component provides the input in which users can type the text they’d like to search for. Once the search field is populated with text, it renders the PostsList component (which we’ll create next), providing the search query to it as a prop.

    9. Create a new /src/PostsList.js file and paste in this code:

    import React from 'react';
    
    // Helper function for formatting dates.
    const formatDate = date => new Date( date ).toDateString();
    
    const PostCard = ({post}) => {
      const { postId, title, date, author, featuredImage } = post;
      const { name: authorName } = author;
    
      return (
        
    { featuredImage && // If a featured image exists, display it. {featuredImage.altText} }

    {title}

    Date: {formatDate(date)} Author: {authorName}
    ); }; export default PostCard;

    This is where the magic happens ✨. At the top, we’re defining a POSTS_SEARCH_QUERY GraphQL query. It takes in a search string as an argument and tells WPGraphQL to search for WordPress blog posts that match it, and send back their data. Notice that unlike a REST API where you have no control over which data is sent back in the response, here we are telling WPGraphQL exactly what data we’d like to get back, and the shape to put it in.

    In GraphQL, “edges” represent connections between nodes, and “node” is a generic term for an object – in our case those objects will be blog posts.

    You can also see that we’re using the Query component and passing to it our query as well as the search string to use as the argument it gets. Query handles all the heavy lifting and provides a render prop. We are immediately destructuring the three props we receive into loading, error, and data variables. After that we have some declarative JSX code to handle all possible scenarios. Different things are rendered depending on whether:

    • the query is currently in progress (loading)
    • an error has occurred
    • matching posts were NOT found, or
    • matching posts WERE found

    If matching posts were found, we map over them and render out a PostCard component for each (which we’ll create next).

    10. And now for our final PostCard component that will handle rendering each individual post card. Create a new /src/PostCard.js file and paste in this code:

    import React from 'react';
    
    // Helper function for formatting dates.
    const formatDate = date => new Date( date ).toDateString();
    
    const PostCard = ({post}) => {
      const { postId, title, date, author, featuredImage } = post;
      const { name: authorName } = author;
    
      return (
        
    { featuredImage && // If a featured image exists, display it. {featuredImage.altText} }

    {title}

    Date: {formatDate(date)} Author: {authorName}
    ); }; export default PostCard;

    That’s it! Once those four JS files and one CSS file are in place, you should be able to run npm start (if the app’s not already running), then visit http://localhost:3000/ and try searching for some blog posts. Any string you type will be used to search both blog post titles and their content, and the matching results will pop into view.

    Let’s contrast our app from one using a traditional REST API for a minute –
    If you were to build an app like this using a REST API, you’d potentially have to make multiple requests back to the server to get all the data you need. The first REST endpoint may take in a search string as an argument and respond with a list of the post IDs for the matching search results. You’d then have to take those post IDs and make another request back to the server to get all of the data you need for those posts (title, date, author, featured image, etc.). Extra, synchronous round trips like that back to the server can be expensive and slow down your frontend app. By contrast, with GraphQL, everything can be fetched in one request. For example, you could build a complex query for getting the most recent 10 posts, then for each of the authors of those, get some of their user data (name, email, etc.) as well as a list of their 3 most recent posts in a particular category. If you’re using GraphQL, all of that data could be fetched from the server in a single request and returned to your frontend app all at once, formatted in exactly the way you requested.

    This example app merely scratches the surface of what can be done with these technologies. You can dig into the documentation for WPGraphQL to learn more about working with mutations (changing or deleting data), implementing authentication, defining your own GraphQL types, connections and resolvers, and much more.

    Apollo Client also has lots more to offer from sending requests for mutations to the server (in addition to query requests, like the one we send in this example app), caching query data locally, providing you with a global app data store using Apollo Link State, pagination, and many other features.

    Now go forth and see what other cool things you can build with these technologies. ????