# Joystream Query Node Joystream query node can be generated by using `substrate-query-node/cli`. ## Getting Started Cli create a folder named `generated` and put everthing inside it. ```text $ cli codegen ``` Start graphql server: ```text $ cd generated/graphql-server $ yarn start:dev ``` Start block indexer: ```text $ cd generated/indexer $ yarn start ``` ## Add a new mapping for Joystream MemberRegistered event 1. Every mapping function get a parameter of `DB` type ```typescript import { DB } from '../generated/indexer'; ``` 1. `db` object is for database operations save/get/remove and access to event itself 2. Define the event handler function with the following signature and import the entity class ```typescript import { MemberRegistereds } from '../generated/indexer/entities/MemberRegistereds'; export async function handleMemberRegistered(db: DB) {} ``` 1. Inside the handler function create a new instance of the entity and fill properties with event data. ```typescript // Get event data const { AccountId, MemberId } = db.event.event_params; const member = new MemberRegistereds({ accountId: AccountId.toString(), memberId: +MemberId }); ``` 1. Call `db.save()` method to save data on database ```typescript // Save to database. db.save(member); ``` 1. Query database ```typescript // Query from database const findOptions = { where: { memberId: 123 } }; // match the record const m = await db.get(MemberRegistereds, findOptions); ``` Below you can find the complete code **Complete code** ```typescript import { MemberRegistereds } from "../generated/indexer/entities/MemberRegistereds"; import { DB } from "../generated/indexer"; export async function handleMemberRegistered(db: DB) { // Get event data const { AccountId, MemberId } = db.event.event_params; const member = new MemberRegistereds({ accountId: AccountId.toString(), memberId: +MemberId }; // Save to database. db.save(member); // Query from database const m = await db.get(MemberRegistereds, { where: { memberId: 123 } }); } ``` ## Query Node Constructs Explained 1. `schema.graphql` is where you define types for graphql server. Graphql server use these types to generate db models, db tables, graphql resolvers. Below you can find a type defination example: ```graphql type Membership { # Member's root account id accountId: String! # Member's id memberId: Int! # The unique handle chosen by member handle: String # A Url to member's Avatar image avatarUri: String # Short text chosen by member to share information about themselves about: String } ``` **Important** Relationship between types not supported yet! 1. Block indexer is block consumer and every block can have events that we want to store their data. So indexing data from events we need to send the event to a function or a class that can handle the event and stores the event data on the database. `mappings` are the functions that we use to update our database with events data. Functions that we define in our mappings will be called only when the event name match our function name \(function name pattern is `'handle' + eventName`\). We call mapping functions as event handlers. Each event handler have only one parameter which is the `db: DB`. Every database operation is made with `db` object and the event can be accessed with `db` object. Below you can find an example for the event a handler: ```typescript // mappings/index.ts import { DB } from '../generated/indexer'; export function handleMemberRegistered(db: DB) { console.log(`Event parameters: ${db.event.event_params}`); } ``` 1. Block indexer connects to a blockchain node via WebSocket so we need to tell block indexer where to find the address of the node. Also, on the initialization of the indexer, we must pass the type register function as a parameter. So we put these variables inside the `.env` file that indexer can find and use them. For Joystream we will be running a local development node and add the name of the function, the package for the type registration: ```text WS_PROVIDER_ENDPOINT_URI=ws://localhost:9944 TYPE_REGISTER_PACKAGE_NAME=@joystream/types TYPE_REGISTER_FUNCTION=registerJoystreamTypes ``` 1. Database connections options are defined in `.env`: ```text DB_NAME=test DB_USER=postgres DB_PASS=postgres DB_HOST=localhost DB_PORT=5432 GRAPHQL_SERVER_PORT=4000 ```