hasura / go-graphql-client

Package graphql provides a GraphQL client implementation.
MIT License
405 stars 94 forks source link

How to execute a GraphQL query that can not be translated into a struct? #40

Closed piavgh closed 2 years ago

piavgh commented 2 years ago

For the context, I need to query data from this subgraph https://thegraph.com/hosted-service/subgraph/piavgh/uniswap-v3-arbitrum?selected=playground

HTTP endpoint is: https://api.thegraph.com/subgraphs/name/piavgh/uniswap-v3-arbitrum

Previously, I used github.com/machinebox/graphql, the query I used in the code is:

    req := graphql.NewRequest(fmt.Sprintf(`{
        pools(
            subgraphError: allow,
            where : {
                createdAtTimestamp_gte: %v
            },
            first: %v,
            skip: %v,
            orderBy: createdAtTimestamp,
            orderDirection: asc
        ) {
            id
            liquidity
            sqrtPrice
            createdAtTimestamp
            tick
            feeTier
            token0 {
                id
                name
                symbol
                decimals
            }
            token1 {
                id
                name
                symbol
                decimals
            }
        }
    }`, lastCreatedAtTimestamp, first, skip),
    )

How can I translate this query into the kind of struct that hasura/go-graphql-client supports? Especially this part:

(
            subgraphError: allow,
            where : {
                createdAtTimestamp_gte: %v
            },
            first: %v,
            skip: %v,
            orderBy: createdAtTimestamp,
            orderDirection: asc
        )

Thanks

hgiasac commented 2 years ago

It's possible to translate to struct. You can use variables for the above conditions. However the graphql tool doesn't returns schema documentation, so I can't know what input type the schema is.

query GetPools($createdAtTimestamp_gte: Int!, $first: Int!, $skip: Int!) {
  pools(
    subgraphError: allow,
    where : {
      createdAtTimestamp_gte: $createdAtTimestamp_gte
    },
    first: $first,
    skip: $skip,
    orderBy: createdAtTimestamp,
    orderDirection: asc
  ) {
    id
    liquidity
    sqrtPrice
    createdAtTimestamp
    tick
    feeTier
    token0 {
      id
      name
      symbol
      decimals
    }
    token1 {
      id
      name
      symbol
      decimals
    }
  }
}

Variables

{
  "createdAtTimestamp_gte": 0,
  "first": 10,
  "skip":0
}

type TokenItem struct {
    ID       string `graphql:"id"`
    Name     string `graphql:"name"`
    Symbol   string `graphql:"symbol"`
    Decimals string `graphql:"decimals"`
}

type poolQuery struct {
    Pools []struct {
        ID                 string    `graphql:"id"`
        Liquidity          string    `graphql:"liquidity"`
        SqrtPrice          string    `graphql:"sqrtPrice"`
        CreatedAtTimestamp string    `graphql:"createdAtTimestamp"`
        Tick               string    `graphql:"tick"`
        FeeTier            string    `graphql:"feeTier"`
        Token0             TokenItem `graphql:"token0"`
        Token1             TokenItem `graphql:"token1"`
    } `graphql:"pools(subgraphError: allow, where:{ createdAtTimestamp_gte: $createdAtTimestamp_gte },first: $first,skip: $skip,orderBy: createdAtTimestamp,orderDirection: asc)"`
}

variables := map[string]interface{} {
    "createdAtTimestamp_gte": graphql.Int,
    "first": graphql.Int,
    "skip": graphql.Int,
}

client.Query(ctx, &poolQuery, variables)

Otherwise, you also can input pre-built query string directly with Exec https://github.com/hasura/go-graphql-client#execute-pre-built-query

piavgh commented 2 years ago

@hgiasac : thank you