webonyx / graphql-php

PHP implementation of the GraphQL specification based on the reference implementation in JavaScript
https://webonyx.github.io/graphql-php
MIT License
4.64k stars 566 forks source link

Query Depth Limit per Type #673

Open abdullahseba opened 4 years ago

abdullahseba commented 4 years ago

Is there a way to limit the depth of a query per type? I have seen the query limit validator, but that appears applies to all queries. Some of my queries need a lower limit than others.

{
  user(id: 1) {
    userName
    roles {
      name
      users {
        userName
        roles {
          name
        }
      }
    }
  }
}

This is a many to many relationship, but I want to limit the depth two 2 without affecting other queries that may require a longer depth. This doesn't necessarily have to be the existing validator; If I could get the depth count and throw an error, that would do.

I did search around in previous issues and found a reference to adding rules to the context in the resolver, but I was not sure how this could be implemented.

https://github.com/webonyx/graphql-php/issues/453#issuecomment-470167862

spawnia commented 4 years ago

We are currently lacking documentation for the QueryPlan.

@keulinho you provided the initial implementation of this feature, could you a write up a small section for the docs? I think https://github.com/webonyx/graphql-php/blob/master/docs/executing-queries.md might be a good place for it.

abdullahseba commented 4 years ago

Does the QueryPlan do this then? I've tried print_r on $info->lookAhead() but couldn't find anything useful. I tried the various other sub-functions too from looking at the code but there is very little if any information in the Doc Blocks so I'm not even sure what it's supposed to do. I did find my way around other code that wasn't documented because they were well commented!

The nearest I can come is $info->getFieldSelection(100) and setting the depth to something ridiculous and then measure the depth manually. But this feels far too 'hacky'.

spawnia commented 4 years ago

Does the QueryPlan do this then?

Not yet, but as @vladar hinted in #453, it may be a useful addition. Without documentation, the usefulness of this class is quite limited.

Some utility methods on it might help too, e.g.:

/**
 * Returns the maximum depth of the nested queries.
 *
 * If no further nesting occurs, this returns 0.
 */
public function depth(): int
sebastienbarre commented 4 years ago

Hi. I do have another use case for this issue.

I have QueryDepth set to 5, and this works fine for my application so far... Except that it broke GraphiQL as soon as I set it, and that's very unfortunate because I need that tool for development, manual testing, debugging, etc. GraphiQL is reporting "Max query depth should be 5 but got 11.". Is this something you guys know how to deal with?

Thank you

UPDATE: never mind, this can be done by checking if operationName is 'IntrospectionQuery'. If that is the case, do not add the QueryDepth() rule.