hive-console-sdk 0.3.21

Rust SDK for Hive Console
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
## 0.3.21 (2026-08-25)

### Fixes

#### Fix the router process aborting on supergraph hot-reload when `telemetry.hive.usage_reporting` is enabled.

Retiring a supergraph drops the previous generation's Hive usage-reporting agent.

That agent used to flush on drop via a blocking bridge (`block_in_place`) that is only valid on a multi-threaded `tokio` runtime.
The router runs on ntex's current-thread runtime, so this always panicked, and since the panic happened inside a `Drop` impl, it escalated to a full process abort (`panic in a destructor during cleanup`) instead of just failing the reload.

The agent now uses a non-blocking flush, best-effort operation instead.

Fixes https://github.com/graphql-hive/router/issues/1439

## 0.3.20 (2026-08-16)

### Fixes

#### Stop cancellation from interrupting an active usage flush

The usage agent now observes cancellation while waiting for the next flush interval instead of checking only after the full interval has elapsed. Cancellation remains pending while an active flush completes, preventing a drained report batch from being lost when its send future is interrupted.

## 0.3.19 (2026-07-26)

### Fixes

#### Support custom GraphQL root type names

Hive Router now reads `query`, `mutation`, and `subscription` root type names from the schema instead of assuming they are named `Query`, `Mutation`, and `Subscription`.

## 0.3.18 (2026-07-20)

### Fixes

#### Improve GraphQL operation validation

- **Faster validation (2-3x):** rules now share a single `OperationVisitor` pass over the operation document instead of each rule visiting it independently.
- **New `UniqueInputFieldNames` rule:** input object fields are now kept as a list rather than a map, so duplicate fields are no longer silently deduplicated before validation. A query like `{ field(input: { value: 1, value: 2 }) }` is now correctly rejected.
- **Fixed `VariablesInAllowedPosition`:** now accounts for default values on variables, field arguments, and input object fields. Nullable variables used in a non-null argument that defines a default are no longer incorrectly rejected.

## 0.3.17 (2026-06-30)

### Fixes

#### Fix: Traverse fragments linearly during cycle validation and inlining

GraphQL fragments can spread other fragments, e.g. `fragment A on T { ...B }`. When fragments form a long acyclic chain (A spreads B, B spreads C, and so on for thousands of links), we walked that chain with plain recursion. 

This change prevents the stack from being filled in such cases.

## 0.3.16 (2026-06-15)

### Features

#### Add at-least-once sampling for Usage Reporting

Hive Router now supports at-least-once sampling for Usage Reporting.

This feature is useful when you want to keep a low sampling rate, but still make sure all operations are visible in Hive at least once.

The first request for each unique key is always reported. Later requests for the same key follow the configured sampling `rate`.

Example configuration:

```yaml
telemetry:
  hive:
    usage_reporting:
      enabled: true
      sampling:
        rate: "10%" # 10% of operations will be reported
        at_least_once:
          key: # the combination of operation's name and body makes the request unique
            - operation_name
            - operation_body
          max_distinct_keys: 12000 # how many keys to track and hold in memory
```

Keys are tracked in memory, up to `max_distinct_keys` (default: `100_000`). Every key takes approximately 16 bytes of memory.

#### Apply usage-reporting excludes before sampling

Exclusion of Usage Reports is now evaluated before sampling. Excluded operations are dropped immediately and sampling is not affected.

## 0.3.15 (2026-06-13)

### Fixes

- Version bump and update `vrl` to latest

## 0.3.14 (2026-05-27)

### Fixes

#### Fix `VariablesInAllowedPosition` rejecting list-typed variables with a non-null default value

The router used to reject valid client queries that declared a list-typed variable with a non-null default value, for example:

```graphql
query Q($arg: [SomeEnum!] = SOME_VALUE) {
  field(arg: $arg)
}
```

with a `VariablesInAllowedPosition` validation error containing a malformed type:

```
Variable "$arg" of type "SomeEnum!!" used in position expecting type "[SomeEnum!]".
```

The rule used to compute the variable's effective type incorrectly when the variable was list-typed and had a non-null default value: it dropped the list wrapper and re-wrapped the inner element type in `NonNull`, producing the invalid `T!!` shape. Per [the spec](https://spec.graphql.org/draft/#sec-All-Variable-Usages-are-Allowed), a non-null default value makes the variable usable in a non-null position; the variable's effective type should be `NonNull(var_type)`, not `NonNull(element_type)`. So for `[SomeEnum!]` with a non-null default, the effective type is now correctly `[SomeEnum!]!` (and the query is accepted).

## 0.3.13 (2026-05-26)

### Fixes

#### Remove dependency ntex from console-sdk

Other pkgs are released due to minor refactor and code relocation.

## 0.3.12 (2026-05-19)

### Fixes

#### Fix: pin `ntex` version to `3.7.2` to avoid regressions

This release pins `ntex` to `3.7.2` to avoid regressions, like the one reported in [#997](https://github.com/graphql-hive/router/issues/997). 

Users who builds their own router are impacted by this regression, due to the way Cargo handles unpinned dependencies.

## 0.3.11 (2026-05-17)

### Fixes

#### Implement Circuit Breaker for Subgraph Requests

This change introduces a circuit breaker mechanism for subgraph requests in the Hive Router. The circuit breaker will monitor the success and failure rates of requests to each subgraph and will prevent future requests if the failure rate exceeds a certain threshold. When the circuit breaker is opened, subsequent requests to that subgraph will fail immediately without attempting to send the request.

This implementation helps improve the resilience and stability of the Hive Router when dealing with unreliable subgraphs.

## 0.3.10 (2026-05-05)

### Features

#### Dynamic Exclusions

### Dynamic Exclusions in Hive Router

Hive Router now supports dynamic exclusions, allowing you to exclude specific requests from usage reporting based on custom logic. This feature is useful for scenarios where you want to skip telemetry for certain requests, such as health checks or specific endpoints.

The previous operation-name list format is still supported for backward compatibility.

#### Usage
```diff
- exclude: ['ExcludedOp']
+ exclude:
+   expression: '.request.operation.name == "ExcludedOp"'
```

Both of the following are valid and supported:

```yaml
## legacy format
exclude:
  - ExcludedOp

## dynamic expression format
exclude:
  expression: '.request.operation.name == "ExcludedOp"'
```

The details about expression context is documented in the [Hive Router documentation](https://the-guild.dev/graphql/hive/docs/router/configuration/expressions).

### Dynamic Exclusions in Apollo Router

As in Hive Router, Apollo Router used to support only operation name based exclusions. With the new dynamic exclusions feature, you can now specify custom logic to exclude requests from usage reporting.


## New `add_report_with_request` method in Hive Console SDK

In order to support exclusions based on request properties, a new method `add_report_with_request` has been added to the Hive Console SDK. This method allows you to include the request information in the report, which can then be used in the dynamic exclusion logic.

## 0.3.9 (2026-04-20)

### Features

#### Negative Cache and Single-Flight

Introduced single-flight resolution of documents in the SDK.

Added a negative cache to store non 2XX requests for 5s (configurable, but in SDK it's disabled by default). It's meant to not keep repeating the same requests that eventually give errors or 404s.

#### Persisted Documents

Introduces persisted documents support in Hive Router with configurable extraction and storage backends.

Supports extracting persisted document IDs from:
- `documentId` in request body (default)
- `documentId` in URL query params (default)
- Apollo-style `extensions.persistedQuery.sha256Hash` (default)
- custom `json_path` (for example `doc_id` or `extensions.anything.id`)
- custom `url_query_param` (for example `?doc_id=123`)
- custom `url_path_param` (for example `/graphql/:id`)

Order is configurable and evaluated top-to-bottom.

Supports persisted document resolution from:
- file manifests (Apollo and Relay KV styles)
- Hive CDN (via `hive-console-sdk`)

File storage includes watch mode by default (with 150ms debounce) to reload manifests after file changes.
Hive storage validates document ID syntax before generating CDN paths to avoid silent invalid-path behavior.

Adds persisted-documents metrics:

- `hive.router.persisted_documents.extract.missing_id_total`
- `hive.router.persisted_documents.storage.failures_total`

These help track migration progress and resolution failures in production

## 0.3.8 (2026-03-16)

### Fixes

- Update `regress` to `0.11.0`
- Implements `AsRef` trait for `graphql_tools::parser::query::ast::TypeCondition`

## 0.3.7 (2026-03-05)

### Features

#### Plugin System

This release introduces a Plugin System that allows users to extend the functionality of Hive Router by creating custom plugins.

```rust
use hive_router::plugins::plugin_trait::RouterPlugin;
use hive_router::async_trait;
 
struct MyPlugin;
 
##[async_trait]
impl RouterPlugin for MyPlugin {
    type Config = ();
 
    fn plugin_name() -> &'static str {
        "my_plugin"
    }
}
```

You can learn more about the plugin system in the [technical documentation](https://the-guild.dev/graphql/hive/docs/router/plugin-system) and in [Extending the Router guide](https://the-guild.dev/graphql/hive/docs/router/guides/extending-the-router).

This new feature also exposes many of the Router's internals through the [`hive-router` crate](https://crates.io/crates/hive-router).

### Fixes

#### Dependencies Updates

- Update `rustls`, `aws-lc-rs` and `aws-lc-sys` dependencies to address `PKCS7` CVE in `aws-lc` crates.
- Update `rand` to latest version.

#### Internal GraphQL Validation Cache Key

- `ConsumerSchema` and `ValidationPlan` now implement `hash` property, which is calculated based on the SDL string of the consumer schema and the validation rules when the struct is created or when a new rule is added to the validation plan.
- Validation cache key is generated by hashing the SDL string of the consumer schema, and the validation rules together with the operation itself.
- All schema AST nodes now implement `Hash` trait, which allows us to hash the entire schema AST when generating the validation cache key.

## 0.3.6 (2026-02-06)

### Features

- Operation Complexity - Limit Aliases (#746)
- Operation Complexity - Limit Aliases (#749)

## 0.3.5 (2026-01-27)

### Fixes

#### Fix release issues and conflicts

- Re-export `graphql-tools` from `hive-console-sdk` to make it easier to depend directly on the SDK instead of an external package.

#### Fixed: 4xx client errors are now properly treated as errors and trigger endpoint failover, instead of being returned as successful responses.

This ensures the CDN fallback mechanism works correctly when endpoints return client errors like 403 Forbidden or 404 Not Found.

## 0.3.4 (2026-01-22)

### Fixes

#### Refactor Parse Error Handling in `graphql-tools`

Breaking;
- `ParseError(String)` is now `ParseError(InternalError<'static>)`.
- - So that the internals of the error can be better structured and more informative, such as including line and column information.
- `ParseError`s are no longer prefixed with "query parse error: " in their Display implementation.

## 0.3.3 (2026-01-16)

### Fixes

#### Add `minify_query_document` for optimized query minification

Implements `minify_query_document` to minify parsed GraphQL operations directly, avoiding the need for an intermediate `Display` step. This new approach uses `itoa` and `ryu` for efficient integer and float formatting.

By minifying the query document representation instead of the query string, we achieve performance improvements: query minification time is reduced from 4μs to 500ns, and unnecessary allocations are eliminated.

Includes benchmarks and tests to validate the performance gains and correctness of the new implementation.

#### Update reqwest default features

In this version, we've updated the `features` used by the `reqwest` dependency. By default, this Crate is using `rustls` for TLS.

## 0.3.2 (2026-01-15)

### Fixes

- Downgrade `reqwest` to `v0.12` to avoid runtime crash from `rustls` `CryptoProvider` introduced in reqwest `v0.13`.

## 0.3.1 (2026-01-14)

### Fixes

#### Update `reqwest`, `reqwest-retry`, and `reqwest-middleware` dependencies

This change updates the `reqwest` dependency to version `0.13.0`, `reqwest-retry` to version `0.9.0`, and `reqwest-middleware` to version `0.5.0` in the Hive Console SDK and Router packages.

#### Moves hive-console-sdk to router repository

This change moves the `hive-console-sdk` package to the Hive Router repository.

## 0.3.0

### Minor Changes

- [#7379](https://github.com/graphql-hive/console/pull/7379)
  [`b134461`](https://github.com/graphql-hive/console/commit/b13446109d9663ccabef07995eb25cf9dff34f37)
  Thanks [@ardatan](https://github.com/ardatan)! - Breaking Changes to avoid future breaking
  changes;

  Switch to [Builder](https://rust-unofficial.github.io/patterns/patterns/creational/builder.html)
  pattern for `SupergraphFetcher`, `PersistedDocumentsManager` and `UsageAgent` structs.

  No more `try_new` or `try_new_async` or `try_new_sync` functions, instead use
  `SupergraphFetcherBuilder`, `PersistedDocumentsManagerBuilder` and `UsageAgentBuilder` structs to
  create instances.

  Benefits;

  - No need to provide all parameters at once when creating an instance even for default values.

  Example;

  ```rust
  // Before
  let fetcher = SupergraphFetcher::try_new_async(
          "SOME_ENDPOINT", // endpoint
           "SOME_KEY",
          "MyUserAgent/1.0".to_string(),
          Duration::from_secs(5), // connect_timeout
          Duration::from_secs(10), // request_timeout
          false, // accept_invalid_certs
          3, // retry_count
      )?;

  // After
  // No need to provide all parameters at once, can use default values
  let fetcher = SupergraphFetcherBuilder::new()
      .endpoint("SOME_ENDPOINT".to_string())
      .key("SOME_KEY".to_string())
      .build_async()?;
  ```

  - Easier to add new configuration options in the future without breaking existing code.

  Example;

  ```rust
  let fetcher = SupergraphFetcher::try_new_async(
          "SOME_ENDPOINT", // endpoint
           "SOME_KEY",
          "MyUserAgent/1.0".to_string(),
          Duration::from_secs(5), // connect_timeout
          Duration::from_secs(10), // request_timeout
          false, // accept_invalid_certs
          3, // retry_count
          circuit_breaker_config, // Breaking Change -> new parameter added
      )?;

  let fetcher = SupergraphFetcherBuilder::new()
      .endpoint("SOME_ENDPOINT".to_string())
      .key("SOME_KEY".to_string())
      .build_async()?; // No breaking change, circuit_breaker_config can be added later if needed
  ```

### Patch Changes

- [#7379](https://github.com/graphql-hive/console/pull/7379)
  [`b134461`](https://github.com/graphql-hive/console/commit/b13446109d9663ccabef07995eb25cf9dff34f37)
  Thanks [@ardatan](https://github.com/ardatan)! - Circuit Breaker Implementation and Multiple
  Endpoints Support

  Implementation of Circuit Breakers in Hive Console Rust SDK, you can learn more
  [here](https://the-guild.dev/graphql/hive/product-updates/2025-12-04-cdn-mirror-and-circuit-breaker)

  Breaking Changes:

  Now `endpoint` configuration accepts multiple endpoints as an array for `SupergraphFetcherBuilder`
  and `PersistedDocumentsManager`.

  ```diff
  SupergraphFetcherBuilder::default()
  -    .endpoint(endpoint)
  +    .add_endpoint(endpoint1)
  +    .add_endpoint(endpoint2)
  ```

  This change requires updating the configuration structure to accommodate multiple endpoints.

## 0.2.3

### Patch Changes

- [#7446](https://github.com/graphql-hive/console/pull/7446)
  [`0ac2e06`](https://github.com/graphql-hive/console/commit/0ac2e06fd6eb94c9d9817f78faf6337118f945eb)
  Thanks [@ardatan](https://github.com/ardatan)! - Fixed the stack overflow error while collecting
  schema coordinates from the recursive input object types correctly;

  Let's consider the following schema:

  ```graphql
  input RecursiveInput {
    field: String
    nested: RecursiveInput
  }
  ```

  And you have an operation that uses this input type:

  ```graphql
  query UserQuery($input: RecursiveInput!) {
    user(input: $input) {
      id
    }
  }
  ```

  When collecting schema coordinates from operations that use this input type, the previous
  implementation could enter an infinite recursion when traversing the nested `RecursiveInput` type.
  This would lead to a stack overflow error.

- [#7448](https://github.com/graphql-hive/console/pull/7448)
  [`4b796f9`](https://github.com/graphql-hive/console/commit/4b796f95bbc0fc37aac2c3a108a6165858b42b49)
  Thanks [@kamilkisiela](https://github.com/kamilkisiela)! - export `minify_query` and
  `normalize_operation` functions (mainly for Hive Router)

- [#7439](https://github.com/graphql-hive/console/pull/7439)
  [`a9905ec`](https://github.com/graphql-hive/console/commit/a9905ec7198cf1bec977a281c5021e0ef93c2c34)
  Thanks [@jdolle](https://github.com/jdolle)! - Remove the usage flag (!) from non-null, but unused
  variables to match js sdk

## 0.2.2

### Patch Changes

- [#7405](https://github.com/graphql-hive/console/pull/7405)
  [`24c0998`](https://github.com/graphql-hive/console/commit/24c099818e4dfec43feea7775e8189d0f305a10c)
  Thanks [@ardatan](https://github.com/ardatan)! - Use the JSON Schema specification of the usage
  reports directly to generate Rust structs as a source of truth instead of manually written types

## 0.2.1

### Patch Changes

- [#7364](https://github.com/graphql-hive/console/pull/7364)
  [`69e2f74`](https://github.com/graphql-hive/console/commit/69e2f74ab867ee5e97bbcfcf6a1b69bb23ccc7b2)
  Thanks [@ardatan](https://github.com/ardatan)! - Fix the bug where reports were not being sent
  correctly due to missing headers

## 0.2.0

### Minor Changes

- [#7246](https://github.com/graphql-hive/console/pull/7246)
  [`cc6cd28`](https://github.com/graphql-hive/console/commit/cc6cd28eb52d774683c088ce456812d3541d977d)
  Thanks [@ardatan](https://github.com/ardatan)! - Breaking;

  - `SupergraphFetcher` now has two different modes: async and sync. You can choose between
    `SupergraphFetcherAsyncClient` and `SupergraphFetcherSyncClient` based on your needs. See the
    examples at the bottom.
  - `SupergraphFetcher` now has a new `retry_count` parameter to specify how many times to retry
    fetching the supergraph in case of failures.
  - `PersistedDocumentsManager` new needs `user_agent` parameter to be sent to Hive Console when
    fetching persisted queries.
  - `UsageAgent::new` is now `UsageAgent::try_new` and it returns a `Result` with `Arc`, so you can
    freely clone it across threads. This change was made to handle potential errors during the
    creation of the HTTP client. Make sure to handle the `Result` when creating a `UsageAgent`.

  ```rust
  // Sync Mode
  let fetcher = SupergraphFetcher::try_new_sync(/* params */)
  .map_err(|e| anyhow!("Failed to create SupergraphFetcher: {}", e))?;

  // Use the fetcher to fetch the supergraph (Sync)
  let supergraph = fetcher
      .fetch_supergraph()
      .map_err(|e| anyhow!("Failed to fetch supergraph: {}", e))?;

  // Async Mode

  let fetcher = SupergraphFetcher::try_new_async(/* params */)
  .map_err(|e| anyhow!("Failed to create SupergraphFetcher: {}", e))?;

  // Use the fetcher to fetch the supergraph (Async)
  let supergraph = fetcher
      .fetch_supergraph()
      .await
      .map_err(|e| anyhow!("Failed to fetch supergraph: {}", e))?;
  ```

## 0.1.1

### Patch Changes

- [#7248](https://github.com/graphql-hive/console/pull/7248)
  [`d8f6e25`](https://github.com/graphql-hive/console/commit/d8f6e252ee3cd22948eb0d64b9d25c9b04dba47c)
  Thanks [@n1ru4l](https://github.com/n1ru4l)! - Support project and personal access tokens (`hvp1/`
  and `hvu1/`).

## 0.1.0

### Minor Changes

- [#7196](https://github.com/graphql-hive/console/pull/7196)
  [`7878736`](https://github.com/graphql-hive/console/commit/7878736643578ab23d95412b893c091e32691e60)
  Thanks [@ardatan](https://github.com/ardatan)! - Breaking;

  - `UsageAgent` now accepts `Duration` for `connect_timeout` and `request_timeout` instead of
    `u64`.
  - `SupergraphFetcher` now accepts `Duration` for `connect_timeout` and `request_timeout` instead
    of `u64`.
  - `PersistedDocumentsManager` now accepts `Duration` for `connect_timeout` and `request_timeout`
    instead of `u64`.
  - Use original `graphql-parser` and `graphql-tools` crates instead of forked versions.

## 0.0.1

### Patch Changes

- [#7143](https://github.com/graphql-hive/console/pull/7143)
  [`b80e896`](https://github.com/graphql-hive/console/commit/b80e8960f492e3bcfe1012caab294d9066d86fe3)
  Thanks [@ardatan](https://github.com/ardatan)! - Extract Hive Console integration implementation
  into a new package `hive-console-sdk` which can be used by any Rust library for Hive Console
  integration

  It also includes a refactor to use less Mutexes like replacing `lru` + `Mutex` with the
  thread-safe `moka` package. Only one place that handles queueing uses `Mutex` now.