Search code examples
pythongraphqlapollogql

How to combine list of DocumentNode with named operations into a single DocumentNode with respective named operations in graphql?


I am working on application that has to query graphql to fetch data, but when i combine list of DocumentNodes into single DocumentNode using concat_ast provided by graphql, I m receving the following error graphql.error.graphql_error.GraphQLError: This anonymous operation must be the only defined operation

I know the reason why this is happening, here is the example of what is happening when i combine the querys, the concat function is adding extra braces around each named operation, which is a incorrect graphql query syntax

Combined query

{
  table1: fetchTable1(
    id: [5, 45]
    perPage: 5
    currentPage: 1
  ) {
    data {
      id
      name
    }
  }
}

{
  table2: fetchTable2(table1_id: [5, 45], perPage: 5, currentPage: 1) {
    data {
      id
      customer
    }
  }
}

Individual Query, table2 is its named operation

{
  table2: fetchTable2(table1_id: [5, 45], perPage: 5, currentPage: 1) {
    data {
      id
      customer
    }
  }
}

But i need the combined result to be in the following format, so that all operations will be named, I have also tried this query in apollo graphql UI, and it works, but i could not generate one using concat in python, is there any other ways i could comibne multiple DocumentNodes without affecting the existing named operations.

{
  table1: fetchTable1(
    id: [5, 45]
    perPage: 5
    currentPage: 1
  ) {
    data {
      id
      name
    }
  }

  table2: fetchTable2(table1_id: [5, 45], perPage: 5, currentPage: 1) {
    data {
      id
      customer
    }
  }
}

I have tried using concat_ast function provided by graphql, I also have a workaround in place which is to not create DocumentNodes per each table before and combinne all the tables dict at the end and craete a single DocumentNode, but it would be better to let graphql combine DocumentNodes into one or if any other better solutions than mine as i might need to fetch individual tables in other parts of my application.


Solution

  • We can using graphql-query package for combine GraphQL queries in python.

    Code

    from graphql_query import Argument, Field, Operation, Query
    
    fetchTable1 = Query(
        name="fetchTable1",
        alias="table1",
        arguments=[
            Argument(name="id", value=[5, 45]),
            Argument(name="perPage", value=5),
            Argument(name="currentPage", value=1),
        ],
        fields=[Field(name="data", fields=["id", "name"])]
    )
    
    fetchTable2 = Query(
        name="fetchTable2",
        alias="table2",
        arguments=[
            Argument(name="table1_id", value=[5, 45]),
            Argument(name="perPage", value=5),
            Argument(name="currentPage", value=1),
        ],
        fields=[Field(name="data", fields=["id", "customer"])]
    )
    
    operation = Operation(
        type="query",
        queries=[fetchTable1, fetchTable2],
    )
    
    print(operation.render())
    

    The result is

    query {
      table1: fetchTable1(
        id: [5, 45]
        perPage: 5
        currentPage: 1
      ) {
        data {
          id
          name
        }
      }
    
      table2: fetchTable2(
        table1_id: [5, 45]
        perPage: 5
        currentPage: 1
      ) {
        data {
          id
          customer
        }
      }
    }
    

    And creating DocumentNode:

    query = gql(operation.render())