graphql-composition

Crates.iographql-composition
lib.rsgraphql-composition
version0.4.0
sourcesrc
created_at2023-10-31 15:33:15.55831
updated_at2024-06-11 14:44:22.846577
descriptionAn implementation of GraphQL federated schema composition
homepage
repositoryhttps://github.com/grafbase/grafbase/tree/main/engine/crates/composition
max_upload_size
id1019933
size316,778
Fredrik Björk (fbjork)

documentation

README

graphql-composition

crates.io docs.rs

An implementation of GraphQL federated schema composition.

Example

use graphql_composition::{Subgraphs, compose};

fn main() {
  let user_subgraph = r#"
    extend schema
      @link(url: "https://specs.apollo.dev/federation/v2.3",
            import: ["@key"])

    type Query {
      findUserByEmail(email: String!): User
    }

    type User @key(fields: "id") {
      id: ID!
      name: String!
    }
  "#;

  let cart_subgraph = r#"
    extend schema
      @link(url: "https://specs.apollo.dev/federation/v2.3",
            import: ["@key", "@shareable"])

    type User @key(fields: "id") {
      id: ID!
      cart: Cart
    }

    type Cart @shareable {
      items: [String!]!
    }
  "#;

  let [user_subgraph, cart_subgraph] = [user_subgraph, cart_subgraph]
    .map(|sdl| async_graphql_parser::parse_schema(&sdl).unwrap());

  let mut subgraphs = Subgraphs::default();

  subgraphs.ingest(&user_subgraph, "users-service", "http://users.example.com");
  subgraphs.ingest(&cart_subgraph, "carts-service", "http://carts.example.com");

  let composed = compose(&subgraphs).into_result().unwrap().to_sdl().unwrap();

  let expected = r#"
directive @core(feature: String!) repeatable on SCHEMA

directive @join__owner(graph: join__Graph!) on OBJECT

directive @join__type(
    graph: join__Graph!
    key: String!
    resolvable: Boolean = true
) repeatable on OBJECT | INTERFACE

directive @join__field(
    graph: join__Graph
    requires: String
    provides: String
) on FIELD_DEFINITION

directive @join__graph(name: String!, url: String!) on ENUM_VALUE

enum join__Graph {
    USERS_SERVICE @join__graph(name: "users-service", url: "http://users.example.com")
    CARTS_SERVICE @join__graph(name: "carts-service", url: "http://carts.example.com")
}

type User
    @join__type(graph: USERS_SERVICE, key: "id")
    @join__type(graph: CARTS_SERVICE, key: "id")
{
    cart: Cart @join__field(graph: CARTS_SERVICE)
    id: ID!
    name: String! @join__field(graph: USERS_SERVICE)
}

type Cart {
    items: [String!]!
}

type Query {
    findUserByEmail(email: String!): User @join__field(graph: USERS_SERVICE)
}
  "#;

  assert_eq!(expected.trim(), composed.trim());
}

Features

  • The output is a structured, serializable format with all relevant relationships (FederatedGraph).
  • FederatedGraph can be rendered to GraphQL SDL (see the example above).
  • Good composition error messages.

Status

The crate is being actively developed and maintained.

Commit count: 5396

cargo fmt