Techdozo
  • Microservices
    • All
    • GraphQL
    • gRPC
    • Spring Boot
    GraphQL Error Handling

    GraphQL Error Handling

    Pages

    Spring for GraphQL: Pagination with Code Example

    Spring for GraphQL: Interfaces and Unions

    gRPC Bidirectional Streaming with Code Example

    gRPC Bidirectional Streaming with Code Example

    gRPC Client Streaming

    gRPC Client Streaming

    Distributed transaction in microservices using Saga

    Distributed Transactions in Microservices: implementing Saga with Temporal

  • Spring Boot
    Pages

    Spring for GraphQL: Pagination with Code Example

    Spring Boot GraphQL service

    Getting started with Spring Boot GraphQL service

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    RESTful Microservices with Spring Boot and Kubernetes

    RESTful Microservices with Spring Boot and Kubernetes

    RESTful API Gateway with gRPC

    RESTful API Gateway with gRPC

  • gRPC
    gRPC Bidirectional Streaming with Code Example

    gRPC Bidirectional Streaming with Code Example

    gRPC Client Streaming

    gRPC Client Streaming

    gRPC Interceptor: unary interceptor with code example

    gRPC Interceptor: unary interceptor with code example

    gRPC: synchronous and asynchronous Server streaming RPC

    gRPC: synchronous and asynchronous Server streaming RPC

    Photo by Ramón Salinero on Unsplash

    gRPC: synchronous and asynchronous unary RPC in Java

    Microservices inter-process communication using gRPC

    gRPC for microservices communication

  • GraphQL
    GraphQL Error Handling

    GraphQL Error Handling

    Pages

    Spring for GraphQL: Pagination with Code Example

    Spring for GraphQL: Interfaces and Unions

    GraphQL Directive

    GraphQL Directive

    Spring for GraphQL mutation

    Spring for GraphQL: Mutation

    Spring for GraphQL: How to solve the N+1 Problem?

    Spring for GraphQL: How to solve the N+1 Problem?

    Spring GraphQL with @Controller, @SchemaMapping and @QueryMapping

    Spring for GraphQL : @SchemaMapping and @QueryMapping

    Spring Boot GraphQL service

    Getting started with Spring Boot GraphQL service

  • Kubernetes
    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Components of Kubernetes Architecture

    Components of Kubernetes Architecture

    Helm Chart: quick start your app deployment on Kubernetes

    Helm Chart: quick start your app deployment on Kubernetes

    gRPC load balancing on Kubernetes (using Headless Service)

    gRPC load balancing on Kubernetes (using Headless Service)

    Getting started with Kind: quick start a multi-node local Kubernetes cluster

    Getting started with Kind: quick start a multi-node local Kubernetes cluster

    Getting started with Minikube: deploying application on local Kubernetes cluster

    Getting started with Minikube: deploying application on local Kubernetes cluster

  • Java
    Java Streams: Stream Operation with Examples

    Java Streams: Stream Operation with Examples

    Java Streams: stream creation with examples

    Java Streams: stream creation with examples

    Garbage Collection

    Super Fast Garbage Collectors in Java

    Calculus

    Functional Programming in Java

No Result
View All Result
  • Login
  • Microservices
    • All
    • GraphQL
    • gRPC
    • Spring Boot
    GraphQL Error Handling

    GraphQL Error Handling

    Pages

    Spring for GraphQL: Pagination with Code Example

    Spring for GraphQL: Interfaces and Unions

    gRPC Bidirectional Streaming with Code Example

    gRPC Bidirectional Streaming with Code Example

    gRPC Client Streaming

    gRPC Client Streaming

    Distributed transaction in microservices using Saga

    Distributed Transactions in Microservices: implementing Saga with Temporal

  • Spring Boot
    Pages

    Spring for GraphQL: Pagination with Code Example

    Spring Boot GraphQL service

    Getting started with Spring Boot GraphQL service

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    RESTful Microservices with Spring Boot and Kubernetes

    RESTful Microservices with Spring Boot and Kubernetes

    RESTful API Gateway with gRPC

    RESTful API Gateway with gRPC

  • gRPC
    gRPC Bidirectional Streaming with Code Example

    gRPC Bidirectional Streaming with Code Example

    gRPC Client Streaming

    gRPC Client Streaming

    gRPC Interceptor: unary interceptor with code example

    gRPC Interceptor: unary interceptor with code example

    gRPC: synchronous and asynchronous Server streaming RPC

    gRPC: synchronous and asynchronous Server streaming RPC

    Photo by Ramón Salinero on Unsplash

    gRPC: synchronous and asynchronous unary RPC in Java

    Microservices inter-process communication using gRPC

    gRPC for microservices communication

  • GraphQL
    GraphQL Error Handling

    GraphQL Error Handling

    Pages

    Spring for GraphQL: Pagination with Code Example

    Spring for GraphQL: Interfaces and Unions

    GraphQL Directive

    GraphQL Directive

    Spring for GraphQL mutation

    Spring for GraphQL: Mutation

    Spring for GraphQL: How to solve the N+1 Problem?

    Spring for GraphQL: How to solve the N+1 Problem?

    Spring GraphQL with @Controller, @SchemaMapping and @QueryMapping

    Spring for GraphQL : @SchemaMapping and @QueryMapping

    Spring Boot GraphQL service

    Getting started with Spring Boot GraphQL service

  • Kubernetes
    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Components of Kubernetes Architecture

    Components of Kubernetes Architecture

    Helm Chart: quick start your app deployment on Kubernetes

    Helm Chart: quick start your app deployment on Kubernetes

    gRPC load balancing on Kubernetes (using Headless Service)

    gRPC load balancing on Kubernetes (using Headless Service)

    Getting started with Kind: quick start a multi-node local Kubernetes cluster

    Getting started with Kind: quick start a multi-node local Kubernetes cluster

    Getting started with Minikube: deploying application on local Kubernetes cluster

    Getting started with Minikube: deploying application on local Kubernetes cluster

  • Java
    Java Streams: Stream Operation with Examples

    Java Streams: Stream Operation with Examples

    Java Streams: stream creation with examples

    Java Streams: stream creation with examples

    Garbage Collection

    Super Fast Garbage Collectors in Java

    Calculus

    Functional Programming in Java

No Result
View All Result
Techdozo
No Result
View All Result
Home Microservices GraphQL

Spring for GraphQL: Interfaces and Unions

Pankaj by Pankaj
May 17, 2023
in GraphQL, Microservices
Reading Time: 16 mins read
0
A A
0
ADVERTISEMENT

GraphQL has become increasingly popular among developers since it was open-sourced in 2015. One of the reasons for its popularity is its ability to enable us to retrieve data efficiently through powerful and flexible APIs using concepts such as Interfaces, Unions, and Fragments. In GraphQL, interfaces and unions are abstract types that enable a schema field to return one of several object types. Spring for GraphQL makes implementing interfaces and unions easy and straightforward.

In this article, we’ll understand the general concept of the GraphQL interface and unions and how to implement them in Spring for GraphQL.

ADVERTISEMENT

In this article

  • GraphQL Interface
  • Querying Interface
  • Fragment
  • Multiple Interfaces
  • Interface Best Practices
  • GraphQL Union
  • Interface and Union implementation
    • Implementing Interface
    • Implementing Union
  • Code example
  • Summary

If you’re interested in learning more about GraphQL, be sure to check out our other posts.

  • Spring for GraphQL : @SchemaMapping and @QueryMapping
  • Spring for GraphQL: How to solve the N+1 Problem?
  • Spring for GraphQL: Mutation
  • GraphQL Directive
  • Getting started with Spring Boot GraphQL service

GraphQL Interface

A GraphQL interface is an abstract type similar to an interface in programming languages like Java. A GraphQL field can return multiple concrete object types with the interface, enhancing APIs’ flexibility and efficiency.

For instance, imagine creating a GraphQL API that returns the courses available at a university. The university offers two types of courses: online and offline. To define this API, you can create a GraphQL interface in the following way:


interface Course {
    id : ID!
    name : String!
    price: Float!
    startDate: String!
    endDate: String!
}

Online and offline course types can be defined as follows:


type OnlineCourse implements Course  {
    id : ID!
    name : String!
    price: Float!
    startDate: String!
    endDate: String!
}

type OfflineCourse implements Course {
    id : ID!
    name : String!
    price: Float!
    startDate: String!
    endDate: String!
    location: Location
}

type Location {
    address : String
}

As you can see, both types contain all fields from the Course interface, but OfflineCourse also includes a Location field.

Interfaces are helpful for returning objects or sets of objects of various types. By implementing an interface type, you can simplify your schema and reduce the number of queries needed to retrieve the relevant data. This can improve your application’s efficiency and overall performance.

ADVERTISEMENT

To obtain data about courses, you can use the Query type:


type Query {
    courses: [Course!]!
}

Querying Interface

You can query the common fields of the Course interface type just like any other GraphQL type, as follows:


query GetAllCourse {
  courses {
    id
    name
    price
    startDate
    endDate 
  }
}

Here’s the result returned by the query above:


{
  "data": {
    "courses": [
      {
        "id": "1",
        "name": "Effective Java",
        "price": 20.99,
        "startDate": "01/01/2023",
        "endDate": "01/31/2023"
      },
      ....
      {
        "id": "2",
        "name": "Python Basic",
        "price": 16.99,
        "startDate": "03/01/2023",
        "endDate": "03/31/2023"
      },
      {
        "id": "3",
        "name": "Deep Learning",
        "price": 36.99,
        "startDate": "03/01/2023",
        "endDate": "03/31/2023"
      }
    ]
  }
}

If you add __typename to your query, you will notice that the results include both online and offline courses.


query GetAllCourse {
  courses {
    id
    name
    price
    startDate
    endDate 
    __typename
  }
}

It’s worth mentioning that the __typename field simply returns the name of an object type in string format.

Response of query with __typename


{
  "data": {
    "courses": [
      {
        "id": "1",
        "name": "Effective Java",
        "price": 20.99,
        "startDate": "01/01/2023",
        "endDate": "01/31/2023",
        "__typename": "OnlineCourse"
      },
      ....
      {
        "id": "2",
        "name": "Python Basic",
        "price": 16.99,
        "startDate": "03/01/2023",
        "endDate": "03/31/2023",
        "__typename": "OfflineCourse"
      },
      {
        "id": "3",
        "name": "Deep Learning",
        "price": 36.99,
        "startDate": "03/01/2023",
        "endDate": "03/31/2023",
        "__typename": "OfflineCourse"
      }
    ]
  }
}

If you need to query the location field of an offline course type, you can use special syntax called fragments, as follows:


query GetAllCourseWithLocation {
  courses {
    id
    name
    price
    startDate
    endDate
    ... on OfflineCourse {
      location {
        address
      }
    } 
    
  }
}

Here is the response returned by the query above:


{
  "data": {
    "courses": [
      {
        "id": "1",
        "name": "Effective Java",
        "price": 20.99,
        "startDate": "01/01/2023",
        "endDate": "01/31/2023"
      },
      ...
      {
        "id": "2",
        "name": "Python Basic",
        "price": 16.99,
        "startDate": "03/01/2023",
        "endDate": "03/31/2023",
        "location": {
          "address": "Pune"
        }
      },
      {
        "id": "3",
        "name": "Deep Learning",
        "price": 36.99,
        "startDate": "03/01/2023",
        "endDate": "03/31/2023",
        "location": {
          "address": "New Delhi"
        }
      }
    ]
  }
}

The code ... on OfflineCourseis a special syntax of GraphQL called inline fragments.

Fragment

A GraphQL fragment is a reusable code that can be shared between multiple queries and mutations.

Fragments enable you to reuse sections of GraphQL queries and break down complex queries into smaller, more manageable components.


fragment OfllineCoursePart on OfflineCourse {
  location {
    address
  }
}

query GetAllCourseWithLocation {
  courses {
    id
    name
    price
    startDate
    endDate
    ...OfllineCoursePart
    
  }
}

The above GraphQL query retrieves a list of all courses with their basic information (id, name, price, startDate, endDate) and their location’s address. The address is retrieved by using a fragment called “OfflineCoursePart” that specifies the “address” field of the “location” object within each “OfflineCourse”.

Multiple Interfaces

A GraphQL type can implement multiple interfaces. For example, the following is a valid syntax.


interface CertificateType {
    certificateType : String
}

interface Course {
    id : ID!
    name : String!
    price: Float!
    startDate: String!
    endDate: String!
}

type OnlineCourse implements Course & CertificateType {
    certificateType : String
    id : ID!
    name : String!
    price: Float!
    startDate: String!
    endDate: String!
}

You can query the above GraphQL schema as:


query GetAllCourseWithLocation {
  courses {
    id
    name
    price
    startDate
    endDate
    ... on CertificateType {
      certificateType
    }
    ... on OfflineCourse {
      location {
        address
      }
    }
  }
}

Interface Best Practices

The GraphQL interface enforces constraints requiring an object type to define all fields in that interface. However, creating interfaces solely to enforce field definitions is not considered a best practice.

In the below example, the Nameable interface enforces the name field in disparate types such as Cat, Dog, and Owner.


interface Nameable {
  name: String
}

type Cat implements Nameable {
  name: String
  meowVolume: Int
}

type Dog implements Nameable {
  name: String
  barkVolume: Int
}

type Owner implements Nameable {
  name: String
  cats: [Cat]
  dogs: [Dog]
}

type Query {
  owners: [Owner]
}

This is not a recommended practice for interfaces because this schema does not use Nameable as a return type for a field. This prevents clients from utilizing the polymorphic relationship in their operations.

To learn more, please refer to Recommended usage for GraphQL interfaces.

GraphQL Union

Union types are a helpful feature in GraphQL that lets you combine multiple types into one. This is especially useful when you need to return different objects of various types as a single response to a query. It’s similar to interfaces, but you can’t specify any common fields between the types.

For instance, let’s say you want to retrieve book and movie data in a single query response. You could create a union type called Media that includes both the Book and Movie object types.


union Media = Book | Movie

type Book {
    id : ID
    name : String
    authors : [String]
}

type Movie {
    id : ID
    name : String
    actors : [String]
}

Then, you could define the query as:


type Query {
    allMedia: Media
}

Using a union type in this scenario simplifies your schema and reduces the number of queries required to retrieve the necessary data. This can make your application more efficient and improve overall performance.

When you define a union type, you declare which object types are included in the union. This means that any query that returns a Media object could potentially include a Book or a Movie object, depending on the data that is being queried.


query GetAllMedia {
  allMedia {
    __typename
    ... on Book {
      name
      publisher
      author
    }
    ... on Movie {
      title
      director
      actors
    }
  }
}

The above query returns the response:


{
  "data": {
    "allMedia": [
      {
        "__typename": "Book",
        "name": "Zero to One",
        "publisher": "Crown Business",
        "author": "Peter Thiel"
      },
      {
        "__typename": "Book",
        "name": "The Lean Startup",
        "publisher": "VIKIN",
        "author": "Eric Ries"
      },
      {
        "__typename": "Movie",
        "title": "The Shawshank Redemption",
        "director": "Frank Darabont",
        "actors": [
          "Tim Robbins",
          "Morgan Freeman",
          "Bob Gunton"
        ]
      },
      {
        "__typename": "Movie",
        "title": "The Godfather",
        "director": "Francis Ford Coppola",
        "actors": [
          "Marlon Brando",
          "Al Pacino",
          "James Caan"
        ]
      }
    ]
  }
}

Overall, union types can be an incredibly powerful tool in GraphQL, enabling you to create more flexible and efficient schemas.

Interface and Union implementation

Java polymorphism feature makes it very straightforward to implement interface and union in Spring for GraphQL.

Implementing Interface

Let’s implement the below query in Spring for GraphQL


type Query {
    courses: [Course!]!
}

To implement the above query type we can define the marker interface Course as:


public interface Course {
}

And provide implementations of OnlineCourse and OfflineCourse as:


public record OnlineCourse(Integer id, String name, Double price, String startDate, String endDate)
    implements Course {}

public record OfflineCourse(
    Integer id, String name, Double price, String startDate, String endDate, Location location)
    implements Course {}

And in the controller class, you can define @QueryMapping as:


@QueryMapping()
public Collection<Course> courses() {
  log.info("Fetching all courses..");
  return List.of(
      new OnlineCourse(1, "Effective Java", 20.99, "01/01/2023", "01/31/2023"),
      new OnlineCourse(2, "Learning Python", 16.99, "03/01/2023", "03/31/2023"),
      new OnlineCourse(2, "Deep Learning", 36.99, "04/01/2023", "04/30/2023"),
      new OfflineCourse(
          1, "Java Basic", 20.99, "01/01/2023", "01/31/2023", new Location("Mumbai")),
      new OfflineCourse(
          2, "Python Basic", 16.99, "03/01/2023", "03/31/2023", new Location("Pune")),
      new OfflineCourse(
          3, "Deep Learning", 36.99, "03/01/2023", "03/31/2023", new Location("New Delhi")));
}

You can read more about mapping GraphQL queries to implementation Spring for GraphQL : @SchemaMapping and @QueryMapping.

Implementing Union

Like Interface, you can implement union using the Java polymorphism feature.


type Query {
    allMedia: [Media]
}
union Media = Book | Movie

To implement the above query type you can define the marker interface Media as:


public interface Media {}
public record Book(String name, String publisher, String author) implements Media {}
public record Movie(String title, String director, List<String> actors) implements Media {}

And in the controller class, you can define @QueryMapping as:


@QueryMapping()
public Collection<Media> allMedia() {
  log.info("Fetching all media..");
  return List.of(
      new Book("Zero to One", "Crown Business", "Peter Thiel"),
      new Book("The Lean Startup", "VIKIN", "Eric Ries"),
      new Movie(
          "The Shawshank Redemption",
          "Frank Darabont",
          List.of("Tim Robbins", "Morgan Freeman", "Bob Gunton")),
      new Movie(
          "The Godfather",
          "Francis Ford Coppola",
          List.of("Marlon Brando", "Al Pacino", "James Caan")));
}

That’s it. It’s as simple as it gets.

Code example

The working code example of this article is listed on GitHub. To run the example, clone the repository and import graphql-interface as a project in your favorite IDE as a Gradle project.

Summary

In this article, we saw an overview of GraphQL interfaces, unions, and fragments. With interfaces, a field in GraphQL can return various object types, while unions can merge multiple types into a single one. Fragments are reusable bits of code that can be shared across distinct queries and mutations. We also saw examples of how to use interfaces and unions in Spring for GraphQL.

Tags: graphql
Previous Post

gRPC Bidirectional Streaming with Code Example

Next Post

Spring for GraphQL: Pagination with Code Example

Pankaj

Pankaj

Software Architect @ Schlumberger ``` Cloud | Microservices | Programming | Kubernetes | Architecture | Machine Learning | Java | Python ```

Related Posts

GraphQL Error Handling
GraphQL

GraphQL Error Handling

August 9, 2023
Pages
GraphQL

Spring for GraphQL: Pagination with Code Example

July 26, 2023
gRPC Bidirectional Streaming with Code Example
gRPC

gRPC Bidirectional Streaming with Code Example

February 17, 2023
gRPC Client Streaming
gRPC

gRPC Client Streaming

January 20, 2023

Recent Articles

GraphQL Error Handling

GraphQL Error Handling

August 9, 2023
Pages

Spring for GraphQL: Pagination with Code Example

July 26, 2023

Spring for GraphQL: Interfaces and Unions

May 17, 2023
gRPC Bidirectional Streaming with Code Example

gRPC Bidirectional Streaming with Code Example

February 17, 2023
  • Trending
  • Comments
  • Latest
gRPC Bidirectional Streaming with Code Example

gRPC Bidirectional Streaming with Code Example

February 17, 2023
Deploying a RESTful Spring Boot Microservice on Kubernetes

Deploying a RESTful Spring Boot Microservice on Kubernetes

August 18, 2021
gRPC Interceptor: unary interceptor with code example

gRPC Interceptor: unary interceptor with code example

April 30, 2022
Temporal Workflow Orchestration

Workflow Orchestration with Temporal and Spring Boot

October 29, 2022
Calculus

Functional Programming in Java

0
Java Streams: stream creation with examples

Java Streams: stream creation with examples

0
Garbage Collection

Super Fast Garbage Collectors in Java

0
Java Streams: Stream Operation with Examples

Java Streams: Stream Operation with Examples

0
GraphQL Error Handling

GraphQL Error Handling

August 9, 2023
Pages

Spring for GraphQL: Pagination with Code Example

July 26, 2023

Spring for GraphQL: Interfaces and Unions

May 17, 2023
gRPC Bidirectional Streaming with Code Example

gRPC Bidirectional Streaming with Code Example

February 17, 2023
Facebook Twitter Pinterest

TECHDOZO

Simplifying modern tech stack!

Browse by Category

  • Bitesize
  • GraphQL
  • gRPC
  • Java
  • Kubernetes
  • Microservices
  • Spring Boot

Recent Articles

GraphQL Error Handling

GraphQL Error Handling

August 9, 2023
Pages

Spring for GraphQL: Pagination with Code Example

July 26, 2023

© 2023 Techdozo.

Welcome Back!

Sign In with Google
OR

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Home
  • gRPC
  • Kubernetes
  • Microservices
  • GraphQL

© 2023 Techdozo.