Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/justin-tay/federation-jvm-elide-example
Apollo Federation JVM example implementation using Spring for GraphQL and Elide
https://github.com/justin-tay/federation-jvm-elide-example
elide federation graphql java
Last synced: about 1 month ago
JSON representation
Apollo Federation JVM example implementation using Spring for GraphQL and Elide
- Host: GitHub
- URL: https://github.com/justin-tay/federation-jvm-elide-example
- Owner: justin-tay
- License: apache-2.0
- Created: 2023-06-27T07:39:53.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-10-25T07:04:19.000Z (about 1 year ago)
- Last Synced: 2023-10-25T08:47:52.664Z (about 1 year ago)
- Topics: elide, federation, graphql, java
- Language: Java
- Homepage: https://elide.io
- Size: 69.3 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Federation JVM Elide Example
This example demonstrates GraphQL Federation with Elide.
This uses Spring GraphQL to contribute a subgraph that integrates with the subgraph contributed by Elide.
## Demo
1\. Ensure that the Elide Spring Boot Example has GraphQL Federation enabled```yaml
elide:
graphql:
federation:
enabled: true
```2\. Run the Elide Spring Boot Example
```bash
mvn spring-boot:run
```Graphiql can be accessed at http://localhost:8080/graphiql/index.html.
3\. Run the Federation JVM Elide Example
```bash
mvn spring-boot:run
```Graphiql can be accessed at http://localhost:8081/graphiql?path=/graphql.
4\. Ensure Rover CLI is installed
Rover is the command-line interface for managing and maintaining graphs with Apollo GraphOS.
```bash
npm install -g @apollo/rover
```5\. Start Rover CLI in separate consoles
Elide Spring Boot Example
```bash
rover dev --name groups --url http://localhost:8080/graphql/api
```Federation JVM Elide Example
```bash
rover dev --name reviews --schema ./src/main/resources/graphql/schema.graphqls --url http://localhost:8081/graphql
```6\. Query Editor
Access http://localhost:4000 for the query editor.## Queries
### Entity Query on JVM Elide Example
The Federation JVM Elide Example extends the `Group` entity on the Elide Spring Boot Example with the `groupReviews` field.
This requires the `Group` on Federation JVM Elide Example to have the `@key` directive.
```
type Group @key(fields: "name") @extends {
name: DeferredID! @external
groupReviews: [GroupReview!]!
}
```The following query is an example that starts from the `Group` entity on Elide Spring Boot Example.
```
query {
group {
edges {
node {
commonName
groupReviews {
stars
text
}
}
}
}
}
```The router calls Federation JVM Elide Example with the following query to add the additional fields to the `Group` entity.
```
query {
_entities(representations: [{__typename: "Group", name: "com.yahoo.elide"}]) {
... on Group {
stars
text
}
}
}
```The mapping for the representations to the Group is configured in the entity data fetcher in `com.example.reviews.config.GraphQLConfiguration`.
```java
DataFetcher> entityDataFetcher = env -> {
List> representations = env.getArgument(_Entity.argumentName);
return representations.stream().map(representation -> {
// Assume only a single id key and no composite keys
String idKey = representation.keySet().stream().filter(key -> !"__typename".equals(key)).findFirst()
.orElse(null);
String id = (String) representation.get(idKey);
if (GROUP_TYPE.equals(representation.get("__typename"))) {
return new Group(id);
}
return null;
}).toList();
};
```### Entity Query on Elide Spring Boot Example
The Federation JVM Elide Example contains the `Group` entity from Elide Spring Boot Example on the `GroupReview` entity.
This requires the `Group` on Elide Spring Boot Example to have the `@key` directive.
The following is the schema of `Group` on Elide Spring Boot Example.
```
type Group @key(fields : "name") {
commonName: String
description: String
name: DeferredID
products(after: String, data: [ProductInput], filter: String, first: String, ids: [String], op: ElideRelationshipOp = FETCH, sort: String): ProductConnection
}
```The following is the schema of `GroupReview` on Federation JVM Elide Example.
```
type GroupReview {
id: ID!,
text: String
stars: Int!
group: Group
}
```The following query is an example that starts from the `GroupReview` entity on Federation JVM Elide Example and references the `Group` on Elide Spring Boot Example.
```
query {
groupReviews {
id
stars
text
group {
name
commonName
}
}
}
```The router calls Elide Spring Boot Example with the following query.
```
query {
_entities(representations: [{__typename: "Group", name: "com.yahoo.elide"}]) {
... on Group {
name
commonName
}
}
}
```Elide will determine the projection in `GraphQLEntityProjectionMaker`.
The `EntitiesDataFetcher` will fetch a list of `NodeContainer`.
```java
public class EntitiesDataFetcher implements DataFetcher> {
...
}
```The `EntityTypeResolver` will map the `NodeContainer` to the appropriate `GraphQLObjectType`.
## Schema
Elide uses a custom scalar `DeferredID` instead of `ID`.
This needs to be registered with the Federation JVM Elide Example subgraph.
The following is the schema definition.
```
scalar DeferredID
```The following is the Java code for the `GraphQLScalarType`.
```java
public class GraphQLScalars {
public static GraphQLScalarType DEFERRED_ID = GraphQLScalarType.newScalar().name("DeferredID")
.description("The DeferredID scalar type represents a unique identifier.")
.coercing(new Coercing() {
@Override
public String serialize(Object o) {
return o.toString();
}@Override
public String parseValue(Object o) {
return o.toString();
}@Override
public String parseLiteral(Object o) {
if (o instanceof StringValue stringValue) {
return stringValue.getValue();
}
if (o instanceof IntValue intValue) {
return intValue.getValue().toString();
}
return o.toString();
}
}).build();
}
```The following is the Java code for registering the scalar in `GraphQLConfiguration`.
```java
@Bean
public GraphQlSourceBuilderCustomizer graphqlSourceBuilderCustomizer() {
return schemaResourceBuilder -> schemaResourceBuilder
.configureRuntimeWiring(runtimeWiring -> runtimeWiring.scalar(GraphQLScalars.DEFERRED_ID));
}
```