Skip to content

Commit

Permalink
QueryApi docs update (#1444)
Browse files Browse the repository at this point in the history
* Update sidebars.json

* update screenshots

* Update hype-indexer.md

* Update posts-indexer.md

* Update feed-indexer.md

---------

Co-authored-by: Roshaan Siddiqui <[email protected]>
  • Loading branch information
bucanero and roshaans authored Jul 24, 2023
1 parent fb3ab4f commit ebbae31
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 7 deletions.
87 changes: 87 additions & 0 deletions docs/bos/tutorial/indexer-tutorials/feed-indexer.md
Original file line number Diff line number Diff line change
Expand Up @@ -595,3 +595,90 @@ async function _handlePostUnlike(postId, likeAuthorAccountId) {
```
Here we also search for an existing relevant post in the `posts` table and if one has been found, the `accountsLiked` is defined as to update it removing the account ID of the account that has performed the like action. Then a graphQL `delete` query is called to remove the like from the `post_likes` table.
## Querying data from the indexer
The final step is querying the indexer using the public GraphQL API. This can be done by writing a GraphQL query using the GraphiQL tab in the code editor.
For example, here's a query that fetches `likes` from the _Feed Indexer_, ordered by `block_height`:
```graphql
query MyQuery {
<user-name>_near_feed_indexer_post_likes(order_by: {block_height: desc}) {
account_id
block_height
post_id
}
}
```
Once you have defined your query, you can use the GraphiQL Code Exporter to auto-generate a JavaScript or BOS Widget code snippet. The exporter will create a helper method `fetchGraphQL` which will allow you to fetch data from the indexer's GraphQL API. It takes three parameters:
- `operationsDoc`: A string containing the queries you would like to execute.
- `operationName`: The specific query you want to run.
- `variables`: Any variables to pass in that your query supports, such as `offset` and `limit` for pagination.
Next, you can call the `fetchGraphQL` function with the appropriate parameters and process the results.
Here's the complete code snippet for a BOS component using the _Feed Indexer_:
```js
const QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql/`;

State.init({
data: []
});

const query = `query MyFeedQuery {
<user-name>_near_feed_indexer_post_likes(order_by: {block_height: desc}) {
account_id
block_height
post_id
}
}`

function fetchGraphQL(operationsDoc, operationName, variables) {
return asyncFetch(
QUERYAPI_ENDPOINT,
{
method: "POST",
headers: { "x-hasura-role": `<user-name>_near` },
body: JSON.stringify({
query: operationsDoc,
variables: variables,
operationName: operationName,
}),
}
);
}

fetchGraphQL(query, "MyFeedQuery", {}).then((result) => {
if (result.status === 200) {
if (result.body.data) {
const data = result.body.data.<user-name>_near_feed_indexer_post_likes;
State.update({ data })
console.log(data);
}
}
});

const renderData = (a) => {
return (
<div key={JSON.stringify(a)}>
{JSON.stringify(a)}
</div>
);
};

const renderedData = state.data.map(renderData);
return (
{renderedData}
);
```
:::tip
To view a more complex example, see this widget which fetches posts with proper pagination: [Posts Widget powered By QueryAPI](https://near.org/edit/roshaan.near/widget/query-api-feed-infinite).
:::
103 changes: 100 additions & 3 deletions docs/bos/tutorial/indexer-tutorials/hype-indexer.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ The `comments` table has columns:
- `receipt_id`: the receipt ID of the transaction that created the comment
- `content`: the content of the comment

## Defining the Indexing Logic
## Defining the indexing logic

The next step is to define the indexing logic. This is done by editing the `indexingLogic.js` file in the code editor. The logic for this indexer can be divided into two parts:

1. Filtering blockchain transactions for a specific type of transaction
2. Saving the data from the filtered transactions to the database

### Filtering Blockchain Transactions
### Filtering Blockchain transactions

The first part of the logic is to filter blockchain transactions for a specific type of transaction. This is done by using the `getBlock` function. This function takes in a block and a context and returns a promise. The block is a Near Protocol block, and the context is a set of helper methods to retrieve and commit state. The `getBlock` function is called for every block on the blockchain.

Expand Down Expand Up @@ -130,7 +130,7 @@ async function getBlock(block: Block, context) {
Again, like with the [`posts-indexer`](./posts-indexer.md) or the [`feed-indexer`](./feed-indexer.md), this filter selects transactions that are of type `FunctionCall` to the `set` method on the contract `social.near` on the network. In addition, it searches for `post` or `index` string in the data for the call.
### Saving the Data to the Database
### Saving the data to the Database
The second part of the logic is to save the data from the filtered transactions to the database. This section also performs the filtering of transactions for posts and comments that contain "PEPE" or "DOGE" in the contents.
Expand Down Expand Up @@ -278,3 +278,100 @@ The logic for this looks like:
}
}
```
## Querying data from the indexer
The final step is querying the indexer using the public GraphQL API. This can be done by writing a GraphQL query using the GraphiQL tab in the code editor.
For example, here's a query that fetches `posts` and `comments` from the _Hype Indexer_, ordered by `block_height`:
```graphql
query MyQuery {
<user-name>_near_hype_indexer_posts(order_by: {block_height: desc}) {
account_id
block_height
content
}
<user-name>_near_hype_indexer_comments(order_by: {block_height: desc}) {
account_id
block_height
content
}
}
```
Once you have defined your query, you can use the GraphiQL Code Exporter to auto-generate a JavaScript or BOS Widget code snippet. The exporter will create a helper method `fetchGraphQL` which will allow you to fetch data from the indexer's GraphQL API. It takes three parameters:
- `operationsDoc`: A string containing the queries you would like to execute.
- `operationName`: The specific query you want to run.
- `variables`: Any variables to pass in that your query supports, such as `offset` and `limit` for pagination.
Next, you can call the `fetchGraphQL` function with the appropriate parameters and process the results.
Here's the complete code snippet for a BOS component using the _Hype Indexer_:
```js
const QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql/`;

State.init({
data: []
});

const query = `query MyHypeQuery {
<user-name>_near_hype_indexer_posts(order_by: {block_height: desc}) {
account_id
block_height
content
}
<user-name>_near_hype_indexer_comments(order_by: {block_height: desc}) {
account_id
block_height
content
}
}`

function fetchGraphQL(operationsDoc, operationName, variables) {
return asyncFetch(
QUERYAPI_ENDPOINT,
{
method: "POST",
headers: { "x-hasura-role": `<user-name>_near` },
body: JSON.stringify({
query: operationsDoc,
variables: variables,
operationName: operationName,
}),
}
);
}

fetchGraphQL(query, "MyHypeQuery", {}).then((result) => {
if (result.status === 200) {
if (result.body.data) {
const data = result.body.data.<user-name>_near_hype_indexer_posts;
State.update({ data })
console.log(data);
}
}
});

const renderData = (a) => {
return (
<div key={JSON.stringify(a)}>
{JSON.stringify(a)}
</div>
);
};

const renderedData = state.data.map(renderData);
return (
{renderedData}
);
```
:::tip
To view a more complex example, see this widget which fetches posts with proper pagination: [Posts Widget powered By QueryAPI](https://near.org/edit/roshaan.near/widget/query-api-feed-infinite).
:::
87 changes: 87 additions & 0 deletions docs/bos/tutorial/indexer-tutorials/posts-indexer.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,90 @@ The `context.graphql` function for this indexer looks like this:
);
}
```
## Querying data from the indexer
The final step is querying the indexer using the public GraphQL API. This can be done by writing a GraphQL query using the GraphiQL tab in the code editor.
For example, here's a query that fetches `posts` from the _Posts Indexer_, ordered by `block_height`:
```graphql
query MyQuery {
<user-name>_near_posts_indexer_posts(order_by: {block_height: desc}) {
content
block_height
account_id
}
}
```
Once you have defined your query, you can use the GraphiQL Code Exporter to auto-generate a JavaScript or BOS Widget code snippet. The exporter will create a helper method `fetchGraphQL` which will allow you to fetch data from the indexer's GraphQL API. It takes three parameters:
- `operationsDoc`: A string containing the queries you would like to execute.
- `operationName`: The specific query you want to run.
- `variables`: Any variables to pass in that your query supports, such as `offset` and `limit` for pagination.
Next, you can call the `fetchGraphQL` function with the appropriate parameters and process the results.
Here's the complete code snippet for a BOS component using the _Posts Indexer_:
```js
const QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql/`;

State.init({
data: []
});

const query = `query MyPostsQuery {
<user-name>_near_posts_indexer_posts(order_by: {block_height: desc}) {
content
block_height
account_id
}
}`

function fetchGraphQL(operationsDoc, operationName, variables) {
return asyncFetch(
QUERYAPI_ENDPOINT,
{
method: "POST",
headers: { "x-hasura-role": `<user-name>_near` },
body: JSON.stringify({
query: operationsDoc,
variables: variables,
operationName: operationName,
}),
}
);
}

fetchGraphQL(query, "MyPostsQuery", {}).then((result) => {
if (result.status === 200) {
if (result.body.data) {
const data = result.body.data.<user-name>_near_posts_indexer_posts;
State.update({ data })
console.log(data);
}
}
});

const renderData = (a) => {
return (
<div key={JSON.stringify(a)}>
{JSON.stringify(a)}
</div>
);
};

const renderedData = state.data.map(renderData);
return (
{renderedData}
);
```
:::tip
To view a more complex example, see this widget which fetches posts with proper pagination: [Posts Widget powered By QueryAPI](https://near.org/edit/roshaan.near/widget/query-api-feed-infinite).
:::
27 changes: 23 additions & 4 deletions website/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -561,13 +561,27 @@
]
},
{
"Community Components": ["bos/community/indexers"]
"BOS API": [
"bos/api/home",
"bos/api/cache",
"bos/api/clipboard",
"bos/api/fetch",
"bos/api/near",
"bos/api/primitives",
"bos/api/social",
"bos/api/state",
"bos/api/storage"
]
},
{
"BOS API": ["bos/api/home", "bos/api/cache", "bos/api/clipboard", "bos/api/fetch", "bos/api/near", "bos/api/primitives", "bos/api/social", "bos/api/state", "bos/api/storage"]
"Dev Tools": [
"bos/dev/intro",
"bos/dev/vscode",
"bos/dev/bos-loader"
]
},
{
"Dev Tools": ["bos/dev/intro", "bos/dev/vscode", "bos/dev/bos-loader"]
"Indexing Tools": ["bos/community/indexers"]
},
{
"type": "html",
Expand Down Expand Up @@ -618,7 +632,12 @@
"value": "<span class='menu__link'><b><small> NEAR Social </small></b></span>"
},
{
"Social DB": ["social/intro", "social/contract", "social/standards", "social/tech"]
"Social DB": [
"social/intro",
"social/contract",
"social/standards",
"social/tech"
]
}
],
"integrate": [
Expand Down
Binary file modified website/static/docs/assets/QAPIScreen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified website/static/docs/assets/QAPIScreen2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ebbae31

Please sign in to comment.