Building Viewer Queries

This guide is for you to build queries on your own if you find that the existing developer guides don't have the information you need.

In GraphQL, there's a pattern called the viewer field. Think of it as a way to get information about the user who's currently logged in. Essentially, it represents the authenticated User.

So why do we use it? This viewer field lets you access details and resources tied to the current user. In simpler terms, it's all about the person using the system and the actions they can take (the actor).

If you've worked with REST APIs, you might be familiar with the /me endpoint. The viewer field in GraphQL serves a similar purpose, giving you a snapshot of the current user's details.

Basic Viewer Query

To query the viewer basic information, you can use the following GraphQL query:

QueryGraphQL
query {
  viewer {
    userId
    firstName
    lastName
  }
}

Which results in the following response:

ResponseJSON
{
  "data": {
    "viewer": {
      "userId": "2c96e455-f753-470f-aa8a-d2cde97a48d4",
      "firstName": "John",
      "lastName": "Doe"
    }
  }
}

Understanding Viewer Relationships

Think of the viewer as the starting point or the "root" of our data graph. From this point, it branches out to connect with various other resources.

For instance, one viewer might be a member of several Organization groups. Each of these organizations can be linked to multiple Network entities they can access.

graph TD V([Viewer]) --> O1[Organization 1] V --> O2[Organization 2] V --> O3[Organization 3] O1 --> N1_1[Network 1.1] O1 --> N1_2[Network 1.2] O2 --> N2_1[Network 2.1] O2 --> N2_2[Network 2.2] O3 --> N3_1[Network 3.1] O3 --> N3_2[Network 3.2]

To query the viewer's Organization with their associated role and Network within the same query, you can use the following GraphQL query:

QueryGraphQL
query {
  viewer {
    lastName
    organizations(first: 10) {
      edges {
        node {
          viewer {
            role
          }
          orgId
          name
          networks(first: 10) {
            edges {
              node {
                networkId
                network {
                  protocolName
                  networkName
                }
              }
            }
          }
        }
      }
    }
  }
}

Which results in the following response:

ResponseJSON
{
  "data": {
    "viewer": {
      "lastName": "Doe",
      "organizations": {
        "edges": [
          {
            "node": {
              "viewer": {
                "role": "OWNER"
              },
              "orgId": "868202983161",
              "name": "My Organization",
              "networks": {
                "edges": [
                  {
                    "node": {
                      "networkId": "a3fbe3f1-079c-4277-83d4-da14337ae795",
                      "network": {
                        "protocolName": "Ethereum",
                        "networkName": "Goerli Testnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "3e467c19-1cce-4e6b-837d-df7e7ca0aa5f",
                      "network": {
                        "protocolName": "Binance Smart Chain",
                        "networkName": "Testnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "6c0bd9a3-e780-4336-8886-440f47ba2951",
                      "network": {
                        "protocolName": "Arbitrum",
                        "networkName": "Goerli Testnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "3b0533ea-62c2-491f-bd26-80627f84cbe2",
                      "network": {
                        "protocolName": "Ethereum",
                        "networkName": "Sepolia Testnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "21ab1b28-37e1-4c11-beb1-38491828d9c1",
                      "network": {
                        "protocolName": "Polygon",
                        "networkName": "Mumbai Testnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "b1b40f41-e1f7-4245-9f07-95352cb19756",
                      "network": {
                        "protocolName": "Binance Smart Chain",
                        "networkName": "Mainnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "cda65477-9c60-4f35-a010-9c2323d80d8c",
                      "network": {
                        "protocolName": "Ethereum",
                        "networkName": "Mainnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "61c8a6aa-e9cd-4b28-8b83-047d3d1e07f5",
                      "network": {
                        "protocolName": "Arbitrum",
                        "networkName": "Sepoila Testnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "c805ffba-b209-4133-9260-b9a0c88ece00",
                      "network": {
                        "protocolName": "Polygon",
                        "networkName": "Mainnet"
                      }
                    }
                  },
                  {
                    "node": {
                      "networkId": "768b36ce-4e43-46db-87c1-74a32aaf9395",
                      "network": {
                        "protocolName": "Arbitrum",
                        "networkName": "Mainnet"
                      }
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
}

Finding your Organization ID

The viewer field is a great way to find your Organization ID. In many mutations and queries that you will use to integrate with Levain, you'll need to specify the Organization ID.

You can use the following GraphQL query to get a list of the first 10 organizations you're a member of:

QueryGraphQL
query {
  viewer {
    organizations(first: 10) {
      edges {
        node {
          orgId
          name
        }
      }
    }
  }
}

Which results in a response similar to the following, with your orgId:

ResponseJSON
{
  "data": {
    "viewer": {
      "organizations": {
        "edges": [
          {
            "node": {
              "orgId": "868202983161",
              "name": "My Organization"
            }
          }
        ]
      }
    }
  }
}

Querying with Resource ID

Starting a query from the viewer and digging deep until you reach your desired resource is possible. However, if you already know the resource's ID, there's a more efficient way to get the information you need.

Let's say you're looking for an Organization with the specific ID orgId of 868202983161. Instead of navigating through multiple levels, you can directly use this ID in your GraphQL query:

QueryGraphQL
query {
  # Replace the orgId below with your orgId
  organization(orgId: "868202983161") {
    name
  }
}

This method is not only direct but also improves the speed and efficiency of your query. You'll reduce the complexity of the query, get smaller response sizes, and ultimately boost performance.

Refer to Query Organization using GraphQL for more examples on how to query Organization resources efficiently.