使用The Graph 索引链上RDF数据
The GraphQL API是Relation基于The Graph开发的链上图数据查询服务
概述
在部署Semantic SBT合约后,项目方可以通过对接The Graph 服务
,来获取链上SBT对应的RDF数据。
在获取到RDF数据后,项目方可以自行选择对应的图数据库来存储从链上的RDF数据。
本文档以AWS的Neptune为例,演示如何将链上RDF数据保存至图数据中。
具体步骤:
通过The Graph获取到数据实体中的RDF数据内容,即链上数据的turtle数据对象
通过调用合约的schemaURI
方法查询RDF对应的数据schema。
将schema和turtle数据对象按SPARQL UPDATE语法格式拼接成对应的图数据库插入语句。
GraphQL API服务介绍
数据访问方式:
通过The Graph 官方提供的webUI(playground)的方式查询
数据实体
txnHash: The transaction hash in blockchain.
blockNumber: The block number.
contract: The contract address.
owner: The token owner of SBT.
tokenId: The token id of SBT.
Web UI的方式查询
GraphQL API项目地址:
https://thegraph.com/hosted-service/subgraph/relationlabs/semantic-sbt
可以登录后可以通过The Graph提供的playground进行查询
HTTP REST 请求
查询最近两条(对应参数 first:2
)token对应的数据实体
curl --location --request POST 'https://api.thegraph.com/subgraphs/name/relationlabs/semantic-sbt' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"{\n turtles(first: 2) {\n id\n owner\n tokenId\n turtle\n }\n}"}'
查询结果
{"data":{"turtles":[{"id":"33456276423","owner":"0x16ff7821a8d293cd2ea07b650fc69ea9206d0615","tokenId":"1","turtle":":Activity1 p:name \"Activity_2049_1\" . :Activity1 p:level 1 . "},{"id":"33456276425","owner":"0x16ff7821a8d293cd2ea07b650fc69ea9206d0615","tokenId":"2","turtle":":Activity2 p:name \"Activity_2049_2\" . :Activity2 p:level 2 . "}]}}
通过JS Client的方式查询
安装 @apollo/client 和 graphql组件
npm install @apollo/client graphql
初始化client
import { ApolloClient, InMemoryCache, gql } from '@apollo/client'
const APIURL = 'https://api.thegraph.com/subgraphs/name/relationlabs/semantic-sbt'
const tokensQuery = `
query($first: Int, $contract: String) {
turtles(
first: $first, contract: $contract
) {
id
tokenId
owner
turtle
}
}
const client = new ApolloClient({
uri: APIURL,
cache: new InMemoryCache(),
})
client
.query({
query: gql(tokensQuery),
variables: {
first: 2,
contract: '0xb8eDcD887DF79278E227dAb986cb2a91C2347E02',
},
})
.then((data) => console.log('Subgraph data: ', data))
.catch((err) => {
console.log('Error fetching data: ', err)
})
获取图数据库对应的Schema
通过调用合约的schemaURI
方法查询schema。
该schema用于构建图数据库时,存储数据时使用。
RDF数据导入图数据库
将turtle数据与对应schema拼接成SPARQL update语句
update=INSERT DATA
{ <https://test.com/s> <https://test.com/p> <https://test.com/o> . }
3. 调用Neptune服务接口保存RDF数据
curl -X POST --data-binary 'update=INSERT DATA { <https://test.com/s> <https://test.com/p> <https://test.com/o> . }' https://your-neptune-endpoint:port/sparql
4. 调用Neptune服务接口查询保存的数据
curl -X POST --data-binary 'query=select ?s ?p ?o where {?s ?p ?o} limit 10' https://your-neptune-endpoint:port/sparql
代码示例
下边通过一段python代码,来示例如何查询链上RDF数据,并保存至Neptune图数据库中的完整过程。
import json
import requests
// 通过The graph的HTTP接口,获取链上对应token的RDF数据,并解析对应的turtle数据对象
def graphql_query():
turtles = []
graphql_endpoint = 'https://api.thegraph.com/subgraphs/name/relationlabs/semantic-sbt'
data = {
'query': '{turtles(where: {contract: "0xb8eDcD887DF79278E227dAb986cb2a91C2347E02", blockNumber_gt: '
'"35661923", blockNumber_lt: "35671923"}) {id owner tokenId turtle}} '
}
res = requests.post(graphql_endpoint, headers={'Content-Type': 'application/json'}, data=json.dumps(data))
print(len(json.loads(res.text)['data']['turtles']))
for item in json.loads(res.text)['data']['turtles']:
turtles.append(item['turtle'])
return turtles
// 将turtle数据对象和对应Schema拼装为sparql格式语句,通过Neptune服务接口,保存至图数据库中
def load_rdf(turtles):
neptune_endpoint = 'https://your-neptune-endpoint:port/sparql'
for turtle in turtles:
sparql = 'update=PREFIX : <http://relationlabs.ai/entity/> ' \
'PREFIX p: <http://relationlabs.ai/property/> ' \
'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ' \
'PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> ' \
'PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> ' \
'INSERT DATA {GRAPH <http://relationlabs.ai/relationship> { ' + turtle + ' }}'
res = requests.post(neptune_endpoint,
headers={'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'},
data=sparql)
print(res.text)
if __name__ == '__main__':
load_rdf(graphql_query())