- Http client request/response use the `HttpHeaders` like `SubgraphHeaders` & `GatewayHeaders` instead of a string list.
- Complete resolver rework replacing both existing field resolver and selection set resolver
- Hook resolver
- Rework of the test SDK
  - The extension path is now automatically inserted when using `"<self>"` url.
  ```rust
  // BEFORE
  let extension_path = std::env::current_dir().unwrap().join("build");
  let extension_path_str = format!("file://{}", extension_path.display());
  let schema = format!(r#"extend schema @link(url: "{path_str}", import: ["@x"])"#);
  // AFTER
  let schema = format!(r#"extend schema @link(url: "<self>", import: ["@x"])"#);
  ```
  - `DynamicSchema` and `DynamicSubgraph` have been merged into `GraphqlSubgraph`.
  ```rust
  // BEFORE
  let subgraph = DynamicSchema::builder(schema)
      .with_resolver("Query", "public", String::from("public"))
      .with_resolver("Query", "private", String::from("private"))
      .into_subgraph("test")
      .unwrap();
  // AFTER
  let subgraph = GraphqlSubgraph::with_schema(schema)
      .with_resolver("Query", "public", String::from("public"))
      .with_resolver("Query", "private", String::from("private"))
      .with_name("test");
  ```
  - `TestConfig` and `TestRunner` have been merged together into `TestGateway`
  ```rust
  // BEFORE
  let config = TestConfig::builder().with_subgraph(subgraph).build(config).unwrap();
  let runner = TestRunner::new(config).await.unwrap();
  // AFTER
  let gateway = TestGateway::builder()
      .subgraph(subgraph)
      .toml_config(config)
      .build()
      .await
      .unwrap();
  ```
  - `graphql_query` and `graphql_subscriptions` have been merged together into `query:`
  ```rust
  // BEFORE
  let response: serde_json::Value = gateway.graphql_query("query { me { id } }")
      .with_header("X-Api-Key", "x")
      .with_variables(serde_json::json!({ "id": "123" }))
      .await
      .unwrap();
  let subscription = gateway.graphql_subscription::<serde_json::Value>(("subscription { me { id } }").await.unwrap();
  // AFTER
  let response = gateway.query("query { me { id } }")
      .header("X-Api-Key", "x")
      .variables(serde_json::json!({ "id": "123" }))
      .send()
      .await;
  let subscription = gateway.query("subscription { me { id } }").ws_stream().await;
  ```
  - Subgraph don't need a dedicated name anymore, a unique one will be generated if absent. Furthermore virtual can be registred throuh a simple string:
  ```rust
  // BEFORE
  TestConfig::builder()
      .with_subgraph(
          DynamicSchema::builder(r#"type Query { public: String! }"#)
            .with_resolver("Query", "public", String::from("public"))
            .into_subgraph("gql")
            .unwrap()
      )
      .with_subgraph(
          DynamicSchema::builder(r#"type Query { hi: String! }"#)
                  .into_extension_only_subgraph("virtual", &extension_path)
                  .unwrap()
      )
  // AFTER (anonymous)
  TestGateway::builder()
      .subgraph(
          GraphqlSubgraph::with_schema(r#"type Query { public: String! }"#)
              .with_resolver("Query", "public", "public")
      )
      .subgraph(r#"type Query { hi: String! }"#)
  // AFTER (named)
  TestGateway::builder()
      .subgraph(
          GraphqlSubgraph::with_schema(r#"type Query { public: String! }"#)
              .with_resolver("Query", "public", "public")
              .with_name("public")
      )
      .subgraph(("virtual", r#"type Query { hi: String! }"#))
      // or
      .subgraph(VirtualSubgraph::new("virtual", r#"type Query { hi: String! }"#))
  ```
