Giter Site home page Giter Site logo

glee2429 / federation-jvm Goto Github PK

View Code? Open in Web Editor NEW

This project forked from apollographql/federation-jvm

0.0 0.0 0.0 849 KB

JVM support for Apollo federation

Home Page: https://www.apollographql.com/docs/federation/

License: MIT License

Java 95.72% Kotlin 4.19% Dockerfile 0.09%

federation-jvm's Introduction

Continuous Integration MIT License Maven Central Join the community forum

Apollo Federation on the JVM

Apollo Federation is a powerful, open architecture that helps you create a unified supergraph that combines multiple GraphQL APIs. graphql-java-support provides Apollo Federation support for building subgraphs in the graphql-java ecosystem. Individual subgraphs can be run independently of each other but can also specify relationships to the other subgraphs by using Federated directives. See Apollo Federation documentation for details.

graph BT;
  gateway([Supergraph<br/>gateway]);
  serviceA[Users<br/>subgraph];
  serviceB[Products<br/>subgraph];
  serviceC[Reviews<br/>subgraph];
  gateway --- serviceA & serviceB & serviceC;
Loading

graphql-java-support is built on top of graphql-java and provides transformation logic to make your GraphQL schemas Federation compatible. SchemaTransformer adds common Federation type definitions (e.g. _Any scalar, _Entity union, Federation directives, etc) and allows you to easily specify your Federated entity resolvers.

This project also provides a set of Federation aware instrumentations:

  • CacheControlInstrumentation - instrumentation that computes a max age for an operation based on @cacheControl directives
  • FederatedTracingInstrumentation - instrumentation that generates trace information for federated operations

Installation

Federation JVM libraries are published to Maven Central. Using a JVM dependency manager, link graphql-java-support to your project.

With Maven:

<dependency>
  <groupId>com.apollographql.federation</groupId>
  <artifactId>federation-graphql-java-support</artifactId>
  <version>${latestVersion}</version>
</dependency>

With Gradle (Groovy):

implementation 'com.apollographql.federation:federation-graphql-java-support:$latestVersion'

Usage

Additional documentation on the Apollo Federation and JVM usage can be found on the Apollo Documentation Portal.

Federation JVM example integrations

Creating Federated Schemas

Using graphql-java (or your framework of choice) we first need to create a GraphQL schema.

Assuming there is already a subgraph that defines a base Product type

# product subgraph
type Query {
  product(id: ID!): Product
}

type Product @key(fields: "id") {
  id: ID!,
  description: String
}

We can create another subgraph that extends Product type and adds the reviews field.

# reviews subgraph
type Product @extends @key(fields: "id") {
    id: ID! @external
    reviews: [Review!]!
}

type Review {
    id: ID!
    text: String
    rating: Int!
}

NOTE: This subgraph does not specify any top level queries.

Using the above schema file, we first need to generate the TypeDefinitionRegistry and RuntimeWiring objects.

SchemaParser parser = new SchemaParser();
TypeDefinitionRegistry typeDefinitionRegistry = parser.parse(Paths.get("schema.graphqls").toFile());
RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring().build();

We can then generate Federation compatible schema using schema transformer. In order to be able to resolve the federated Product type, we need to provide TypeResolver to resolve _Entity union type and a DataFetcher to resolve _entities query.

DataFetcher entityDataFetcher = env -> {
    List<Map<String, Object>> representations = env.getArgument(_Entity.argumentName);
    return representations.stream()
        .map(representation -> {
            if ("Product".equals(representation.get("__typename"))) {
                return new Product((String)representation.get("id"));
            }
            return null;
        })
        .collect(Collectors.toList());
    };
TypeResolver entityTypeResolver = env -> {
    final Object src = env.getObject();
    if (src instanceof Product) {
        return env.getSchema()
            .getObjectType("Product");
    }
    return null;
};

GraphQLSchema federatedSchema = Federation.transform(typeDefinitionRegistry, runtimeWiring)
    .fetchEntities(entityDataFetcher)
    .resolveEntityType(entityTypeResolver)
    .build();

This will generate a schema with additional federated info.

union _Entity = Product

type Product @extends @key(fields : "id") {
  id: ID! @external
  reviews: [Review!]!
}

type Query {
  _entities(representations: [_Any!]!): [_Entity]!
  _service: _Service
}

type Review {
  id: ID!
  rating: Int!
  text: String
}

type _Service {
  sdl: String!
}

scalar _Any

scalar _FieldSet

Instrumentation

Federated Tracing

Tracing your GraphQL queries can provide you detailed insights into your GraphQL layer's performance and usage. Single federated query may be executed against multiple GraphQL servers. Apollo Gateway provides ability to aggregate trace data generated by the subgraphs calls and then send them to Apollo Studio

To make your server generate performance traces and return them along with responses to the Apollo Gateway, install the FederatedTracingInstrumentation into your GraphQL object:

GraphQL graphql = GraphQL.newGraphQL(graphQLSchema)
        .instrumentation(new FederatedTracingInstrumentation())
        .build();

By default, all requests will be traced. In order to skip dev requests and only trace requests that come from the Apollo Gateway, you should populate tracing information in the GraphQLContext map. This will ensure that only requests with apollo-federation-include-trace=ftv1 header value will be traced.

String federatedTracingHeaderValue = httpRequest.getHeader(FEDERATED_TRACING_HEADER_NAME);

Map<Object, Object> contextMap = new HashMap<>();
contextMap.put(FEDERATED_TRACING_HEADER_NAME, federatedTracingHeaderValue);

ExecutionInput executionInput = ExecutionInput.newExecutionInput()
        .graphQLContext(contextMap)
        .query(queryString)
        .build();
graphql.executeAsync(executionInput);

Contact

If you have a specific question about the library or code, please start a discussion in the Apollo community forums.

Contributing

To get started, please fork the repo and checkout a new branch. You can then build the library locally with Gradle

./gradlew clean build

See more info in CONTRIBUTING.md.

After you have your local branch set up, take a look at our open issues to see where you can contribute.

Security

For more info on how to contact the team for security issues, see our Security Policy.

License

This library is licensed under The MIT License (MIT).

federation-jvm's People

Contributors

aivantsov avatar bod avatar caydie-tran avatar dariuszkuc avatar dependabot[bot] avatar glasser avatar jsegaran avatar kenshih avatar lanceon avatar lennyburdette avatar martinbonnin avatar mcohen75 avatar pcarrier avatar renovate[bot] avatar rkudryashov avatar sachindshinde avatar samuelandalon avatar setchy avatar thejc avatar tinnou avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.