Build your First WPGraphQL Extension


目录

Video Tutorial

The following video walks through how to build a WPGraphQL Extension plugin. After watching the video, viewers should be able to create a WordPress plugin that extends the WPGraphQL Schema with new fields.

If you prefer learning these concepts by reading, scroll down to the written tutorial below.

https://youtu.be/0plIW5hf6lM

Prerequisites

Before starting this tutorial, you should have:

What We'll Build

In this tutorial, we'll learn how to:

  1. Create a basic WPGraphQL extension plugin
  2. Register custom types and fields to the GraphQL Schema
  3. Work with WordPress data in your GraphQL API
  4. Follow GraphQL naming conventions and best practices

We'll start with basic concepts using an abstract example, then move on to practical real-world implementations.

Getting Started

Setting Up Your Plugin

  1. Navigate to your WordPress site's wp-content/plugins directory
  2. Create a new folder named my-first-wpgraphql-extension
  3. Create a PHP file with the same name: my-first-wpgraphql-extension.php

Add this code to your PHP file:

<?php
/
Plugin Name: My First WPGraphQL Extension
Description: A tutorial plugin demonstrating WPGraphQL extension development
Version: 1.0.0
Author: Your Name
/
// Prevent direct access to this file
if ( ! defined( 'ABSPATH' ) ) {
  die( 'Unauthorized access!' );
}

After adding this code, activate the plugin in your WordPress admin panel. You should see it listed in the plugins page.

Screenshot showing "My First WPGraphQL Extension" in the WordPress Plugins admin page

Understanding GraphQL Naming Conventions

Before we start extending the schema, it's important to understand GraphQL naming conventions:

These conventions help maintain consistency and clarity in your GraphQL API.

Your First Schema Extension

Let's start with a basic example of extending the schema. We'll create:

We'll create:

<?php
add_action( 'graphql_register_types', function() {
  // Register a custom type
  register_graphql_object_type( 'CustomType', [
    'description' => ( 'An example custom type demonstrating schema extension', 'my-graphql-extension' ),
    'fields' => [
      'message' => [
        'type' => 'String',
        'description' => ( 'A simple message field', 'my-graphql-extension' ),
      ],
      'number' => [
        'type' => 'Int',
        'description' => ( 'A simple number field', 'my-graphql-extension' ),
      ],
    ],
  ]);
  
  // Register a field that returns our custom type
  register_graphql_field( 'RootQuery', 'example', [
    'type' => 'CustomType',
    'description' => ( 'An example field returning our custom type', 'my-graphql-extension' ),
    'resolve' => function() {
      return [
        'message' => 'Hello from your first WPGraphQL extension!',
        'number' => 42,
      ];
    }
  ]);
});

Testing Your First Extension

After adding this code, you can test your extension using GraphiQL in the WordPress admin panel. Navigate to GraphQL → GraphiQL IDE and try this query:

{
  example {
    message
    number
  }
}

You should see a response like:

{
  "data": {
    "example": {
      "message": "Hello from your first WPGraphQL extension!",
      "number": 42
    }
  }
}

Real-World Example: Working with WordPress Options

Now let's look at a practical example. While WPGraphQL automatically exposes some WordPress settings when they're registered with show_in_graphql => true`, you might need to manually expose options or add custom resolution logic.

Here's an example of exposing a custom option:

php
add_action( 'graphql_register_types', function() {
  register_graphql_field( 'RootQuery', 'siteCustomSetting', [
    'type' => 'String',
    'description' => ( 'A custom site setting', 'my-graphql-extension' ),
    'resolve' => function() {
      // Basic capability check
      if ( ! current_user_can( 'read' ) ) {
        throw new \GraphQL\Error\UserError( 'You do not have permission to access this setting' );
      }
      return get_option( 'my_custom_setting', 'default value' );
    }
  ]);
});

After adding this code, you can test your extension using GraphiQL in the WordPress admin panel. Navigate to GraphQL → GraphiQL IDE and try this query:

{
  siteCustomSetting
}

You should see a response like:

{
  "data": {
    "siteCustomSetting": "default value"
  }
}

Advanced Example: Custom Settings Type

Let's create a more complex example with multiple fields and proper error handling:

add_action( 'graphql_register_types', function() {
  // Register a custom settings type
  register_graphql_object_type( 'CustomSiteSettings', [
    'description' => ( 'Custom site settings', 'my-graphql-extension' ),
    'fields' => [
      'mainColor' => [
        'type' => 'String',
        'description' => ( 'The main color theme setting', 'my-graphql-extension' ),
      ],
      'featuredCategories' => [
        'type' => ['list_of' => 'String'],
        'description' => ( 'List of featured category slugs', 'my-graphql-extension' ),
      ],
      'lastUpdated' => [
        'type' => 'String',
        'description' => ( 'When the settings were last updated', 'my-graphql-extension' ),
      ],
    ],
  ]);

  // Register a field that returns our settings type
  register_graphql_field( 'RootQuery', 'customSiteSettings', [
    'type' => 'CustomSiteSettings',
    'description' => ( 'Custom site settings configuration', 'my-graphql-extension' ),
    'resolve' => function() {
      // Check permissions
      if ( ! current_user_can( 'manage_options' ) ) {
        throw new \GraphQL\Error\UserError(( 'You do not have permission to access site settings', 'my-graphql-extension' ));
      }
      try {
        return [
          'mainColor' => get_option( 'site_main_color', '#ffffff' ),
          'featuredCategories' => get_option( 'featured_categories', [] ),
          'lastUpdated' => get_option( 'settings_updated_at' ),
        ];
      } catch ( \Exception $e ) {
        throw new \GraphQL\Error\UserError(( 'Error fetching site settings', 'my-graphql-extension' ));
      }
    }
  ]);

});

You can query these settings with:

{
  siteSettings {
    mainColor
    featuredCategories
    lastUpdated
  }
}

Best Practices

Naming and Documentation

  1. Type Names:
  1. Field Names:
  1. Descriptions:

Security Considerations

Access Control

 register_graphql_field( 'RootQuery', 'sensitiveData', [
    'type' => 'String',
    'resolve' => function() {
        // Always check capabilities
        if ( ! current_user_can( 'manage_options' ) ) {
            throw new \GraphQL\Error\UserError( 'Unauthorized access' );
        }
        
        return get_option( 'sensitive_data' );
    }
]);

Data Sanitization

   'resolve' => function( $source, array $args ) {
       // Always sanitize input
       $safe_input = sanitize_text_field( $args['input'] );
       return wp_kses_post( $safe_input );
   }

Error Handling

Use Try-Catch Blocks

   'resolve' => function() {
       try {
           // Your resolution logic
           return get_option( 'some_option' );
       } catch ( \Exception $e ) {
           throw new \GraphQL\Error\UserError( 
               __( 'Failed to retrieve data', 'my-textdomain' )
           );
       }
   }

Meaningful Error Messages

Troubleshooting Common Issues

If you run into issues, common debugging tips can be found in the Debugging guide.

Next Steps

Explore More Features

Join the Community

Remember to always test your extensions thoroughly and keep security in mind when exposing data through GraphQL.


版本号 #1
由 壳壳虫 创建于 2026-08-29 23:36:26 UTC
由 壳壳虫 更新于 2026-08-29 23:36:26 UTC