🎯 恭喜:您的 WordPress 插件刚刚成为「核心」功能
由于 WP REST API 已随 WordPress 核心一同发布,我过去常常建议避免使用 GraphQL,而是直接使用 REST API 向 WordPress 插件和 Gutenberg 区块提供数据。
但现在不同了。WordPress 6.5 已正式发布,其中包含一项令人惊叹的新功能:Plugin Dependencies。
借助 Plugin Dependencies,任何已在插件目录中发布的 WordPress 插件都可以被定义为我们插件的依赖项,WordPress 会在安装我们的插件之前自动安装该依赖项。
因此,目录中的每个插件实际上都成为了「核心」功能——只要其他插件有需要,它就会被隐式安装。
有些应用场景显而易见,但实际上并不那么必要,例如 WooCommerce 插件声明对 WooCommerce 的依赖——网站所有者很可能已经在使用 WooCommerce 了。
但当所需插件为其他插件提供「工具支持」时,而我们又无法期望网站所有者提前安装该插件(甚至根本不知道它的存在),其带来的影响将会非常显著。
GraphQL 和 Gato GraphQL 正是这种情况。
GraphQL 成为 WordPress 的「核心」功能
GraphQL 是一个用于获取、修改和再次存储 WordPress 站点任意数据的接口。任何需要与数据交互的插件(几乎所有插件都需要)都可以利用 GraphQL 来满足自身需求。
GraphQL 是「工具」,而 Gato GraphQL 是工具提供者。
通过让您的插件声明对 Gato GraphQL 的依赖,GraphQL 服务器将立即可供您的插件使用。
例如,您可以使用 GraphQL 为插件的 Gutenberg 区块获取数据,从而避免创建(和维护)REST 控制器。
这是插件开发者有史以来第一次可以将 GraphQL 视为 WP REST API 的真正替代方案。
插件依赖关系会成为问题吗?
由于作为依赖项安装的插件会出现在 wp-admin 中,不知情的网站所有者可能会理所当然地疑惑:"这是从哪里来的?我被黑了?这是垃圾邮件?究竟发生了什么?"
如果网站所有者感到不满,那将是令人担忧的,因为没有任何插件能承受激怒用户的代价(至少在他们理解情况并接受解决方案之前)。
这种情况可以改善,甚至完全避免。例如,以 Gato GraphQL 作为依赖插件来考虑,Gato GraphQL 也可以提供一个 Lite 版本插件,该版本仅安装一个仅供内部使用、不在 UI 中可见的 GraphQL 服务器。(又是 TODO 列表上的一项新任务!🤷🏻♂️)
对 Gato GraphQL(以及其他插件)而言,更重要的问题是:新站点的安全性会降低吗?
具体到 Gato GraphQL:公开的 GraphQL 端点是否会暴露任何访客都能访问的数据,并可能无意中泄露私人数据?
答案是否定的。Gato GraphQL 默认不启用公开的单一端点,因此可以放心安装,无需担心安全风险。
将 Gato GraphQL 添加为插件依赖项
让我们现在动手,体验这个出色的新功能。
要在插件中使用 GraphQL,您需要在插件头部将 gatographql 声明为插件依赖项:
/**
* Plugin Name: Blocks for cooking recipes
* Requires Plugins: gatographql
*/这样,您的插件就可以通过内部 blockEditor 端点访问数据,该端点在 wp-admin 中以 JavaScript 常量 GATOGRAPHQL_BLOCK_EDITOR_ADMIN_ENDPOINT 的形式提供,指向以下 URL:
https://mysite.com/wp-admin/edit.php?page=gatographql&action=run_query&endpoint_group=blockEditor例如,区块可以使用如下 JavaScript 代码获取数据:
(async function () {
const data = {
query: `
query GetCookingRecipeBlockData($limit: Int) {
posts(pagination: { limit: $limit }) {
id
title
author {
id
name
}
}
}
`,
variables: {
limit: 3
},
};
const response = await fetch(
GATOGRAPHQL_BLOCK_EDITOR_ADMIN_ENDPOINT,
{
method: 'post',
body: JSON.stringify(data),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Content-Length': data.length,
},
credentials: 'include',
}
);
/**
* Execute the query, and await the response
*/
const json = await response.json();
/**
* Check if the query produced errors, otherwise use the results
*/
if (json.errors) {
console.log(JSON.stringify(json.errors));
} else {
console.log(JSON.stringify(json.data));
}
})();如果您希望在 GraphQL query 中使用嵌套 mutations,还可以为插件创建专用的内部端点,并进行相应配置。