本文介绍了Shyft GraphQL Program APIs,它提供了一种更简单有效的方式来查询Solana程序账户数据,作为传统getProgramAccounts()的替代方案,Shyft GraphQL Program APIs允许开发者轻松查询任何程序的账户数据,并支持过滤、排序和分页等功能,从而优化用户体验并简化Solana应用开发流程。
作为 Solana 开发者,我们都熟悉这个重要但具有挑战性的 RPC 调用,getProgramAccounts()。虽然它是查询程序账户数据的首选方法,但其缺点不容忽视。它运行缓慢,你无法像在数据库中那样进行分页和应用过滤器。本质上,它不是生产的理想工具,如果你渴望提供无缝的用户体验,那么仅仅依靠 getProgramAccounts() 是不可行的。
Shyft GraphQL 程序 API 来了,它改变了你与 Solana 程序账户数据交互的方式。简而言之,我们的解决方案允许你轻松地查询任何程序的账户数据,从而为传统的 getProgramAccounts() 提供强大的替代方案。
Twitter 小部件 Iframe
Shyft GraphQL 程序 API 允许你访问 mainnet 和 devnet 程序数据。可以从以下 URL 访问它。
Mainnet:
https://programs.shyft.to/v0/graphql/?api_key={你的-api-key}&network=mainnet-beta
Devnet:
https://programs.shyft.to/v0/graphql/?api_key={你的-api-key}&network=devnet
如果你不想设置代码,或者只是想看看它是如何工作的,你可以访问这些 UI 工具,它们允许你轻松地与我们的 GraphQL 程序 API 交互:
一旦你将你的 GraphQL 端点粘贴到上面的 UI 中,它将自动触发一个自省调用,获取我们当前托管的所有程序的整个 schema。它看起来会像这样
我们现在可以开始利用 Shyft GraphQL 程序 API 从 SPL Governance 程序 中检索提案数据。
要开始,我们需要一些东西。
x-api-key
是一个身份验证参数,它使你有权访问 Shyft API。你可以从 Shyft 网站获得你自己的 API 密钥。 只需在此处使用你的电子邮件 ID 注册,你就可以免费获得它。如果你已经拥有 Shyft API 密钥,请跳过此步骤。
我们在此项目中使用的是 Next JS,但这可以在任何应用程序开发环境中完成。有关 如何在 Next.js 1 3 中设置 GraphQL 的更多信息,请参阅此链接。
你可以从此 repo 克隆本文的完整源代码。
如果你已经熟悉 GraphQL,那么构建查询非常简单。要从 SPL Governance 程序中获取提案,请使用如下查询:
query MyQuery {
GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2 {
abstainVoteWeight
closedAt
denyVoteWeight
descriptionLink
draftAt
executingAt
executionFlags
governance
governingTokenMint
lamports
maxVoteWeight
maxVotingTime
name
options
reserved1
signatoriesCount
signatoriesSignedOffCount
signingOffAt
startVotingAt
state
tokenOwnerRecord
vetoVoteWeight
voteThreshold
voteType
votingAt
votingAtSlot
votingCompletedAt
pubkey
}
}
请注意,我们已包含所有可用的数据字段;但是,你可以随意挑选对你有用的字段。例如,如果你只想要提案的 name 和 pubkey,则查询将如下所示:
query MyQuery {
GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2 {
name
pubkey
}
}
要检索数据,@apollo/client
包提供了几个 React hooks,使我们能够从 GraphQL API 获取数据。在本教程中,我们将使用 useLazyQuery
hook。之所以做出此选择,是因为我们希望在用户单击“搜索”按钮时手动执行查询,而不是在组件挂载时自动执行查询。
const query = gql`
query GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2 {
name
pubkey
}
`;
const [getProposals, { loading, data, fetchMore }] = useLazyQuery(query);
const handleSearch = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
getProposals();
};
结果数据将如下所示
{
"data": {
"GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2": [\
{\
"name": "Pay 0.1 SOL to HAzL8…tEaqf",\
"pubkey": "H8y3YLzB3jVbx5UCY5DBXz2R5rizCBB9uUVoNMacJBRK"\
},\
{\
"name": "NFT",\
"pubkey": "3LGcrfPxtGzM25MGaKzUxefkPrage9EiWK5Dg7RRjtFF"\
},\
{\
"name": "Hackathon_1.0 Prize Split",\
"pubkey": "69Nbj3BH3kji5saLnrDJbvWKwNBqEUWtEV6vEs32nUze"\
}\
]
}
}
我们不仅仅想获取所有提案;我们特别想检索那些名称包含一些用户输入文本的提案。为此,我们需要更新我们的查询以能够接受 variables
query GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV2(
$where: GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_bool_exp
) {
GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2(where: $where) {
name
pubkey
}
}
现在我们可以开始获取数据了。此时,getProposals
函数需要接受变量,即用户输入的文本。
const query = gql`
query GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV2(
$where: GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_bool_exp
) {
GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2(where: $where) {
name
pubkey
}
}
`;
const [getProposals, { loading, data, fetchMore }] = useLazyQuery(query);
const handleSearch = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
getProposals({
variables: {
where: {
name: {
_regex: text,
},
}
}
});
};
我们的 GraphQL API 支持根据我们选择的数据字段对数据进行排序。例如,如果我们想按草案日期按升序对提案进行排序,我们需要更新我们的查询,使其如下所示:
query GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV2(
$where: GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_bool_exp
$orderBy: [GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_order_by!]
) {
GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2(
where: $where
order_by: $orderBy
) {
name
pubkey
}
}
与过滤数据类似,此时,我们的 getProposals
函数需要接受一个用于排序的附加变量。
const query = gql`
query GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV2(
$where: GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_bool_exp
$orderBy: [GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_order_by!]
) {
GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2(
where: $where
order_by: $orderBy
) {
name
pubkey
}
}
`;
const [getProposals, { loading, data, fetchMore }] = useLazyQuery(query);
const handleSearch = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
getProposals({
variables: {
where: {
name: {
_regex: text,
},
},
orderBy: [\
{\
draftAt: "ASC"\
},\
],
}
});
};
众所周知,getProgramAccounts() 目前不支持分页。在单个调用中处理大量数据非常困难,大多数时候会导致连接超时。使用 GraphQL,分页变得非常容易。让我们获取上一个查询并尝试对 proposals account 数据进行分页。
要实现分页,我们可以在查询中指定 limit
和 offset
字段。limit
表示返回的行数,默认为 1000,offset
表示结果集的起始点。
query GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV2(
$where: GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_bool_exp
$orderBy: [GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_order_by!]
$limit: Int
$offset: Int
) {
GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2(
where: $where
order_by: $orderBy
limit: $limit
offset: $offset
) {
name
pubkey
}
}
现在,我们更新 getProposals
函数以接受 limit
和 offset
变量。
const query = gql`
query GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV2(
$where: GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_bool_exp
$orderBy: [GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2_order_by!]
$limit: Int
$offset: Int
) {
GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_ProposalV2(
where: $where
order_by: $orderBy
limit: $limit
offset: $offset
) {
name
pubkey
}
}
`;
const handleSearch = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
getProposals({
variables: {
where: {
name: {
_regex: text,
},
},
orderBy: [\
{\
draftAt: "ASC"\
},\
],
limit: 10,
offset: 0,
}
});
};
设置好所有内容并运行应用程序后,我们会收到如下视频所示的结果。
总之,处理 Solana 的 getProgramAccounts() 具有其挑战性——它速度慢、缺乏过滤等功能,并且不适合流畅的用户体验。但是 Shyft GraphQL 程序 API 来解救了!这些 API 提供了一种更简单、更好的方法来获取 Solana 中的程序账户数据。它们修复了我们使用 getProgramAccounts() 时面临的问题,并使 Solana 开发更灵活、更用户友好。随着 Solana 的发展,Shyft GraphQL 程序 API 等工具对于更顺畅、更高效的开发之旅至关重要。
我们真诚地希望你喜欢阅读这篇博客文章!如果你有任何疑问或想法,请随时访问我们的 Discord 社区。
非常感谢你抽出时间阅读本文!
- 原文链接: blogs.shyft.to/querying-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!