Search code examples
typescriptgraphqlnestjsapollo-server

Accessing the arguments of fields in GraphQL Nest


I'm trying to access the fields of an argument for a GraphQL Query using the Apollo Nest integration.

The issue I'm having is related to nested arguments.

To demonstrate, here is an simplified example of my schema and query:

Schema:

type Company {
    id: Int!,
    test(val: Int!): Int
}

type Query {
    company(id: Int!): Company
}

Query:

query Company {
  company(id: 1) {
    id
    test(val: 2)
  }
}

Working with the company query is easy, the code for this is this:


export class CompaniesResolver {
    constructor(private companiesService: CompaniesService) {}

    @Query('company')
    async getOne(@Args("id") id: number): Promise<Hersteller | null> {
        return await this.companiesService.getOne(id);
    }
}

The thing I'm strugeling with is accessing the val argument from the test field.

I tried to access it with a @ResolveField() Statement like this:

*@ResolveField()
    async test(@Parent() getOne: Function, @Args('val') blorb: number) {
        return val*2;
    } 

This works, but I can't use this, because I need the value of val available during the getOne function call so I can feed it to my ORMs where clause (hidden behind the companiesService.getOne call).

Is there a way to directly access this value from the company resolver?

Any help would be greatly appreciated!


Solution

  • I figured it out!

    Using the graphql-parse-resolve-info library, you can access the abstract sytax tree of the query. This includes access to the arguments of the fields, but is in no way as convenient as using the native nestjs decorators*.

    My code now looks like this (simplified example):

    export class CompaniesResolver {
        constructor(private companiesService: CompaniesService) {}
    
        @Query('company')
        async getOne(@Info() info: GraphQlResolveInfo) {
            let parsedAST = parseResolveInfo(info);
            //print the arguments passed to the "id" field
            console.log(parsedAST.fieldsByTypeName.Company.id.args);
        }
    }
    

    I hope you found this answer helpful :)

    *Directly accessing the query with the native resolvers is impossible, due to the way Apollo works. It creates a resolver chain with nodes for each field, so nested fields will always be handled after the resolver for the first field has ran.

    More Information: https://www.apollographql.com/docs/apollo-server/data/resolvers/#resolver-chains