Expand description
Compute the worst-case node count GitHub’s GraphQL API attributes to a query — offline, from the query text and its page-size variable bindings alone, before the query is ever sent.
§nodeCount, not cost
GitHub meters two different numbers against two different limits, and this crate is about one of them.
nodeCount— the maximum number of nodes one query may return, limited per query atNODE_LIMIT. That is whatnode_countcomputes.cost— the rate-limit points a call spends, metered per hour across everything one credential does.
Neither the code nor these docs computes or claims anything about cost.
§The rules, and where they come from
GitHub publishes them at
https://docs.github.com/en/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api:
node counts multiply down a nested path, sum across sibling paths,
every connection supplies a first or a last inside 1..=100, and the
limit one query may not reach is 500,000. Check this crate against that page
rather than against our confidence.
§No schema, by design
node_count is handed document text and nothing else. It reaches no
network, reads no credential, and consults no GraphQL schema — so it cannot
know which fields are connections by type. Instead:
- a field carrying a
first:or alast:argument is a connection, and multiplies the count beneath it; - every other field contributes no multiplier and no nodes of its own.
That is what makes this crate runnable in a fork pull request with no secret,
which is the whole reason a consumer can put it in a gate. The cost is one
blind spot, stated plainly: a connection that supplies neither first nor
last is invalid to GitHub and invisible here. Such a field is counted as
an ordinary field, so the answer is an undercount rather than an error. A
field supplying both is also invalid to GitHub; the larger of the two is
used, so the answer stays a worst case.
§Example
use github_graphql_node_count::{node_count, NodeCountError, Variables, NODE_LIMIT};
let document = r#"
query($repos: Int!) {
viewer {
repositories(first: $repos) {
edges { node { name issues(first: 10) { edges { node { title } } } } }
}
}
}
"#;
let variables = Variables::from([("repos".to_string(), 50)]);
// 50 repositories + 50 x 10 issues.
assert_eq!(node_count(document, &variables)?, 550);
assert!(node_count(document, &variables)? < NODE_LIMIT);
// A page size GitHub would reject comes back as an error, not a number.
let over = Variables::from([("repos".to_string(), 500)]);
assert!(matches!(
node_count(document, &over),
Err(NodeCountError::PageSizeOutOfRange { .. })
));Structs§
- Position
- Where in the document a problem was found, rendered as
line:column.
Enums§
- Node
Count Error - Why a document’s node count could not be computed.
- Page
Size Argument - Which argument a connection took its page size from.
Constants§
- NODE_
LIMIT - GitHub’s published limit on the number of nodes one query may return.
Functions§
- node_
count - The worst-case number of nodes the one operation in
documentmay return, undervariables, computed by GitHub’s published rules.
Type Aliases§
- Variables
- The integer bound each page-size variable a document names is given, keyed by
variable name without the leading
$.