thecodingmachine / graphqlite

Use PHP Attributes/Annotations to declare your GraphQL API

Home Page:https://graphqlite.thecodingmachine.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Automatic query complexity

oprypkhantc opened this issue · comments

Hey.

There was a similar issue here, see last comment: #306 . What's important here is the following: it'd be nice to have graphqlite automatically compute query complexity using pre-defined settings and an attribute. Some other GraphQL implementations (for other languages) have been doing this for a while and it's pretty neat.

For example, here's a guide from HotChocolate (.NET graphql implementation): https://chillicream.com/docs/hotchocolate/v13/security/operation-complexity

The way they do it is pretty simple: they count every non-object and non-list field as 1, and every object or list or anything with a custom resolver as 5, and allow overriding that through an annotation:

type Query {
  books(take: Int = 10): [Book] @cost(complexity: 5, multipliers:[take])
}

type Book {
  title
  author: Author @cost(complexity: 5)
}

type Author {
  name
}

Given this example, a query like this:

query {
  books {
    title
  }
}

costs 10 (take parameter) * (5 (each Book in books cost) + 1 (title of each Book)) = 10 * (5 + 1) = 60

While a query like that:

query {
  books {
    title
    author {
      name
    }
  }
}

costs 10 * (5 + 1 + 5) = 110.

The implementation consists of a new attribute #[Cost(int $complexity = 1, ?int $defaultMultiplier = null, array $multipliers = [])] and a ComplexityFieldMiddleware. Again, thanks to webonyx/graphql-php supporting query complexity out of the box, it's pretty trivial, yet quite nice.

I've already implemented this in our package and would like to backport this to graphqlite, if there's any interest in it here.

@oprypkhantc Let's do it!

We'll need some good documentation on security and calculating ideal values. How does a multiplier work, and why would you want multiple multipliers - what benefits are there for that, etc.