Enhancing Data as a Service with GraphQL
This article extends the discussions from the earlier blog post Data as a Service (DaaS) using ScyllaDB. To gain a comprehensive understanding of the material covered in this post, I strongly advise you to read the first post to gain more context of Data as a Service (DaaS).
Data as a Service (DaaS) has revolutionized data sharing by enabling secure and efficient access to valuable data across organizational boundaries. In the rapidly advancing realm of data management, the incorporation of GraphQL into the framework of Data as a Service (DaaS) stands out as a pivotal advancement and this post digs into the integration of GraphQL into our DaaS infrastructure, highlighting the benefits and implementation details.
GraphQL: A Paradigm in Data Access
GraphQL enhances Data as a Service (DaaS) by making data retrieval more adaptable and efficient. Unlike conventional REST APIs, GraphQL allows clients to specify their data needs clearly, preventing the unnecessary transfer of excess information.
Some benefits of GraphQL in DaaS:
- Flexible Data Retrieval: Clients define the structure of the response, specifying the data according to their needs, eliminating the need for multiple endpoints, and reducing API complexity.
- GraphQL’s query language: Allows for complex filtering, sorting, and aggregation operations.
- Client-side Optimization: GraphQL empowers clients to optimize data fetching based on their specific requirements, improving performance and reducing server load.
- Versioning and schema changes: GraphQL delivers the explicitly requested data, allowing the addition of new capabilities through the introduction of new types and fields without causing disruptive changes.
Integration with Spring GraphQL
- API Gateway for API management.
- RESTful Spring Boot application for API development.
- GraphQL for Enhanced Data Retrieval.
- ScyllaDB and MySQL for data storage.
Setting up GraphQL
Designing the GraphQL Schema
The schema defines the structure of the data accessible through the API, describing the types of data, their relationships, and the available operations. In this example, the schema includes types for Device
and Location
, along with the relationship between them.
type Query {
deviceById(id: ID): Device
}
type Device {
id: ID
name: String
location: Location
}
type Location {
id: ID
name: String
city: String
country: String
code: Int
}
Data Access Layer
Spring Data JPA is employed to interact with the database, retrieving device and location data based on the provided GraphQL queries.
@GraphQlRepository
public interface DeviceRepository extends Repository<Device, String>, QueryByExampleExecutor<Device> {
Device findById(String id);
}j
The Location repository is quite similar:
@GraphQlRepository
public interface LocationRepository extends Repository<Location, String>, QueryByExampleExecutor<Location> {
Location findById(String id);
}
Configuring the GraphQL Controller
The GraphQL controller serves as the endpoint for handling incoming GraphQL requests. It acts as a bridge between the GraphQL schema and the underlying data access layer, enabling the retrieval and manipulation of the data.
@Controller
public class DeviceController {
private final DeviceRepository deviceRepository;
private final LocationRepository locationRepository;
@Autowired
public DeviceController(DeviceRepository deviceRepository, LocationRepository locationRepository) {
this.deviceRepository = deviceRepository;
this.locationRepository = locationRepository;
}
@QueryMapping
public Device deviceById(@Argument String id) {
return deviceRepository.findById(id);
}
@SchemaMapping(typeName = "Device", field = "location")
public Location location(Device device) {
return locationRepository.findById(device.getLocationId());
}
}
The deviceById
resolver, annotated with @QueryMapping
, retrieves a device with the specified identification using theDeviceRepository
. The location
resolver, annotated with @SchemaMapping
, fetches the location associated with the provided device using the LocationRepository
.
Configuring the GraphQL API Application
To enable the application to serve GraphQL requests, ensure the following configurations are set:
server.port=8083
logging.level.root=info
spring.graphql.graphiql.enabled=true
spring.graphql.schema.printer.enabled=true
spring.graphql.path=/daas/api/graphql
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/daas
spring.datasource.username=user
spring.datasource.password=pass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true
This property spring.graphql.path
specifies the path on which GraphQL requests are received and in this example, the path is set to /daas/api/graphql
.
Enabling GraphQL API Route on API Gateway
To enable the GraphQL API application to be accessed through the API gateway, a new route is configured in the API gateway service:
- id: daas-graphql-api-gateway
uri: http://localhost:8083
predicates:
- Path=/daas/graphql/**
filters:
- SetPath=/daas/api/graphql
This route redirects all incoming requests to the GraphQL API application on the port 8083
, with the path pattern /daas/graphql/**
. The SetPath
filter ensures that the request path is updated to /daas/api/graphql
before reaching the GraphQL API application. This allows the GraphQL API application to recognize the request path and handle it properly.
Live Demo
Now, let’s put GraphQL into action and watch the integration of GraphQL within a microservices architecture, facilitated by an API Gateway.
With both services running, after the following command is executed:
make run
let’s send a simple GraphQL query to the API gateway:
query deviceDetails {
deviceById(id: "device-1") {
name
location {
city
country
}
}
}
This query will retrieve detailed information about a specific device, including its name and location information.
The examples presented here can be found in GitHub repository.