Building And Deploying A Subgraph (Part 2)
Tags: webdev, javascript, beginners, programming
Published: 2024-03-03 20:37:04

Just like how fries can be eaten alone 🍟 or eaten together with either ketchup or mayonnaise, this tutorial is both **1)** a standalone tutorial for deploying and querying a subgraph. **2)** a continuation from my [previous tutorial](https://dev.to/oleanji/build-your-personal-crypto-savings-dapp-part-1-contract-5g8b) on building a savings dapp.


## **Table of contents**
1. [Prerequisites](#requi)
2. [Introduction](#Intro)
3. [Tips to know about subgraphs](#tips)
4. [Initialize Subgraph](#Init)
5. [Tweak Code and Deploy](#code)
6. [Querying Subgraph](#query)
7. [Conclusion](#cons)

### **Prerequisites** <a name="requi"></a>
To build, deploy, and query from a subgraph you will need the following essentials:

- A deployed smart contract (whether verified or not),
- a crypto wallet,
- a [subgraph studio](https://thegraph.com/studio/) account,
- and a cup of coffee ☕.

Before we start building the subgraph project, ensure you have the following above, done? now take a sip 🍵 and let's start building.


### **Introduction** <a name="Intro"></a>
A **subgraph** according to [The Graph](https://thegraph.com/) (which is a decentralized protocol for indexing and querying blockchain data) is a custom API built on blockchain data. They are queried using the GraphQL query language and are deployed to a Graph Node using the Graph CLI.

In simpler terms, a subgraph is like a customizable API for easily querying and getting specific data from a blockchain using GraphQL.

To get started, we need to have a [subgraph studio](https://thegraph.com/studio/) account, which is very easy to do in 2 simple steps;
- Connect your wallet and 
- Sign a message, then you should have a page like this;


![studio](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e55xr7fdqrhs54kbyhaq.png)

Click on the **_Create a Subgraph_** button and enter a subgraph name. You have successfully created a subgraph. well-done!!

## **Tips to know about subgraphs** <a name="tips"></a>

1. Deleting a subgraph is not possible once it's created.
2. Once a subgraph is created, the name cannot be changed.
3. To enable faster and more easy querying of data from a subgraph, the contract associated with it should emit events.
4. Subgraph mappings are written in AssemblyScript therefore using libraries like [ether.js](https://docs.ethers.org/v5/) in the subgraph is not possible.

You can check out more of the tips or FAQs of a subgraph [here](https://thegraph.com/docs/en/developing/developer-faqs/)

## **Initialize Subgraph** <a name="Init"></a>
On the lower right side (you will have to scroll down) of your [dashboard](https://thegraph.com/studio/) page of the subgraph you just created, steps on how to **Initialize**, **Deploy** and **Build** the subgraph are shown.

![Iion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o20cpduhnuuvlw7jrodk.png)

### Following the steps;

- We need to install the graph cli before a subgraph can be initialized.

```
npm install -g @graphprotocol/graph-cli

or

yarn global add @graphprotocol/graph-cli
```

- After the installation, run the below

```
graph init --studio <SUBGRAPH_NAME>
```
Here you will be asked for the _protocol_, _chain_ and other information of the contract you want to subgraph, following the [last tutorial](https://dev.to/oleanji/build-your-personal-crypto-savings-dapp-part-1-contract-5g8b) of writing, deploying and verifying our crypto-saves smart contract, these are the answers to the questions from the terminal:

- Protocol: `ethereum`
- Subgraph Slug: `Crypto-Saves` (or any name you want)
- Directory to create the subgraph in: `Crypto-Saves` (or anywhere you want)
- Ethereum Network: `mumbai` (the chain where the contract was deployed)
- Contract Address: `0x4b1d98af1af713456c1fc86afed67b94c4648f6d` (Contract Address)


![Iption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sio9k7hicilxhzpchdn5.png)

![instal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/saslccwov887dk8zso9r.png)



- After you receive the **Subgraph created** message then run the next command;

```
graph auth --studio <DEPLOY_KEY>
cd <Name_of_subgraph>
```

- Using the events of the contract, the graph auto-generates the subgraph's code which needs little to no tweaking before deployment and publishing. The command below auto-generates the code and then builds it.

```
graph codegen && graph build
```

![n](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/013fifvqrp0cft4asn98.png)

---
Now take another sip of that coffee ☕

## **Tweak Code and Deploy** <a name="code"></a>

Navigate to the `src` folder in the subgraph root directory, then check the auto-generated file, [the graph](https://thegraph.com/) does splendid work and most times the file doesn't need tweaking and you can just deploy directly, but following my tutorial (**Personal Crypto Savings Dapp**) series, a little tweaking is needed.

Change the code in the `schema.graphql` file in the root directory to the following updated code:

```
type EtherLocked @entity(immutable: true) {
  id: ID!
  name: String! # string
  owner: Bytes! # address
  amount: BigInt! # uint256
  releaseTime: BigInt! # uint256
  lockType: String! 
  locked: Boolean
  blockNumber: BigInt!
  blockTimestamp: BigInt!
  transactionHash: Bytes!
}

type EtherUnlocked @entity(immutable: true) {
  id: ID!
  name: String! # string
  owner: Bytes! # address
  amount: BigInt! # uint256
  locked: Boolean
  blockNumber: BigInt!
  blockTimestamp: BigInt!
  transactionHash: Bytes!
}

type LockupTimeExtended @entity(immutable: true) {
  id: ID!
  name: String! # string
  owner: Bytes! # address
  releaseTime: BigInt! # uint256
  blockNumber: BigInt!
  blockTimestamp: BigInt!
  transactionHash: Bytes!
}

type OwnershipTransferred @entity(immutable: true) {
  id: ID!
  previousOwner: Bytes! # address
  newOwner: Bytes! # address
  blockNumber: BigInt!
  blockTimestamp: BigInt!
  transactionHash: Bytes!
}

```

Here I updated the schema and changed some types for better querying results. After this run:

```
graph codegen 
```
This would update the `generated ` folder with the new types and fields obtained from the update of the `schema.graphql`, to complete this we will need to change some things in a file under the `src` folder to:

```
import {
  EtherLocked as EtherLockedEvent,
  EtherUnlocked as EtherUnlockedEvent,
  LockupTimeExtended as LockupTimeExtendedEvent,
  OwnershipTransferred as OwnershipTransferredEvent,
} from "../generated/CryptoSaves/CryptoSaves";
import {
  EtherLocked,
  EtherUnlocked,
  LockupTimeExtended,
  OwnershipTransferred,
} from "../generated/schema";

export function handleEtherLocked(event: EtherLockedEvent): void {
  let entity = EtherLocked.load(event.params.id.toString());

  if (!entity) {
    entity = new EtherLocked(event.params.id.toString());
  }
  entity.name = event.params.name;
  entity.owner = event.params.owner;
  entity.amount = event.params.amount;
  entity.releaseTime = event.params.releaseTime;
  entity.lockType = event.params.lockType;
  entity.locked = true;
  entity.blockNumber = event.block.number;
  entity.blockTimestamp = event.block.timestamp;
  entity.transactionHash = event.transaction.hash;

  entity.save();
}

export function handleEtherUnlocked(event: EtherUnlockedEvent): void {
  let entity = EtherLocked.load(event.params.id.toString());

  if (!entity) {
    return;
  }
  entity.locked = false;
  entity.blockNumber = event.block.number;
  entity.blockTimestamp = event.block.timestamp;
  entity.transactionHash = event.transaction.hash;

  entity.save();
}

export function handleLockupTimeExtended(event: LockupTimeExtendedEvent): void {
  let entity = EtherLocked.load(event.params.id.toString());
  if (!entity) {
    return;
  }
  entity.releaseTime = event.params.releaseTime;
  entity.blockNumber = event.block.number;
  entity.blockTimestamp = event.block.timestamp;
  entity.transactionHash = event.transaction.hash;

  entity.save();
}

export function handleOwnershipTransferred(
  event: OwnershipTransferredEvent
): void {
  let entity = new OwnershipTransferred(event.transaction.hash.toString());
  entity.previousOwner = event.params.previousOwner;
  entity.newOwner = event.params.newOwner;
  entity.blockNumber = event.block.number;
  entity.blockTimestamp = event.block.timestamp;
  entity.transactionHash = event.transaction.hash;

  entity.save();
}

```
I am essentially doing another layer of checks before updating the fields after each event has been emitted.

### Deploy

```
graph deploy --studio <SUBGRAPH_NAME>
```
This deploys your subgraph to production, enabling querying from either the playground or in your front-end application.


![on](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7x87ctsazl3dimjievp1.png)


## Querying Subgraph  <a name="query"></a>
A subgraph can be queried from the frontend application or from the playground that the **subgraph studio** offers, which I find very helpful. 


![Imdescription](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1qwynjt2e9k33phm0zwj.png)

Just like in the image you can write queries on the left side of the playground and get results on the right part. An explorer tab is also on the right part; which auto-generates queries by just clicking on the desired parameters.

Frontend Application querying can be done in 3 different ways:

1. [**Graph client**](https://thegraph.com/docs/en/querying/querying-from-an-application/#graph-client)
2. [**Apollo client**](https://thegraph.com/docs/en/querying/querying-from-an-application/#apollo-client)
3. [**URQL**](https://thegraph.com/docs/en/querying/querying-from-an-application/#urql)

I prefer to use the Apollo client, and I will use this in the frontend aspect of the crypto savings dapp in my next tutorial.

## Conclusion <a name="cons"></a>

Congratulations on making it to the end of this tutorial!🎉 You should now have a good understanding of _what subgraphs are_, why they are useful, and _how to initialize_, _deploy_, and _query_ them. With this knowledge, you can begin creating your subgraphs to interact with various contracts and gain insights into their behavior. Run into a wall? ask away in the comments.

![Its over](https://media.giphy.com/media/t8QSeqwoy0Ol2/giphy.gif?cid=ecf05e47cn6w6sulrsdqpffcpjpz15iohh01zlo6p53o0s53&ep=v1_gifs_search&rid=giphy.gif&ct=g)