GraphQL Server with spring boot by connecting to a remote data base.
GraphQL is a query language for APIs. GraphQL was developed internally by Facebook in 2012 before being publicly released in 2015.
There are many benefits with the GraphQL
1) Ask for what you need and get it exactly.
2) Get many resources in a single request.
3) Improved performance.
Key concepts:
1) schema (Query and Mutation)
2) Resolvers
Schema: schema determines what data you can fetch from querying. here we have types and relationships also.
Query: similar to GET request in the rest Apis. we will use Query for fetching the data.
Mutation: mutation are used create delete and update data. similar to POST,DELETE and PUT in the rest.
consider we have a table called Person in the oracle db. with fields id , name, firstName , lastName and email. now the schema looks like below.
person.graphqls
type Person {
id: Int!
name: String!
firstName: String!
lastName: String!
email: String!
}
type Query {
getPerson(id:Int!): Person
}
type Mutation{
setPerson(id:Int!,name: String!firstName: String!lastName: String!,email:String!):Person
}
we can see from example that getperson method is written in Query it fetches data based on the id, where as setperson method is written in the Mutation it creates a new person.
2) Resolvers:
now we need to write the QueryResolver and mutationResolver to implement the methods in the schema’s query and mutation.
Adding Dependency
in this article we are using the spring boot. To support the GraphQL in the spring boot we need add some dependencies in pom.xml they are
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>3.10.0</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>4.3.0</version>
</dependency>
also add the oracle dependencies
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.1</version>
</dependency>
To connect to Remote Oracle DB:
in application.properties add the following
spring.datasource.url=jdbc:oracle:thin:@//<IP>:1521/oracl
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
we are now connected to remote oracle db and added the graphl, oracle dependencies. now we will add the person schema in to the person.graphqls file.
create a Entity which should match both table in the db and the schema in perso.graphqls.
import javax.persistence.*;
@Entity
@Table(name=”person”)
public class Person {
@Id
@Column(name=”id”, nullable = false)
private int id;
@Column(name=”preferred_name”, nullable = false)
private String name;
@Column(name=”first_name”, nullable = false)
private String firstName;
@Column(name=”last_name”, nullable = false)
private String lastName;
@Column(name=”email”, nullable = false)
private String email;
public Person(){
}
public Person(int id, String name, String firstName, String lastName, String email) {
this.id = id;
this.coreID = coreID;
this.name = name;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
create a repository for the above entity.
import com.example.DemoGraphQL.model.Person;
import org.springframework.data.repository.CrudRepository;
public interface PersonRepository extends CrudRepository<Person, Integer> {
}
now we need to write a resolvers
QueryResolver
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import com.example.DemoGraphQL.model.Person;
import com.example.DemoGraphQL.repository.PersonRepository;
public class Query implements GraphQLQueryResolver {
private PersonRepository personRepository;
public Query(PersonRepository personRepository) {
this.personRepository=personRepository;
}
public Person getPerson(int id){
Person person=personRepository.findOne(125);
return person;
}
}
MutationResolver:
package com.example.DemoGraphQL.resolver;
import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import com.example.DemoGraphQL.repository.PersonRepository;
public class Mutation implements GraphQLMutationResolver {
PersonRepository personRepository;
public Mutation(PersonRepository personRepository) {
this.personRepository = personRepository;
}
public Person newPerson(int id, String name,String firstName, String lastName, String email) {
Person person = new Person();
person.setId(id);
person.setName(name);
person.setFirstName(firstName);
person.setLastName(lastName);
person.setEmail(email);
personRepository.save(author);
return person;
}
}
Application starter:
package com.example.DemoGraphQL;
import com.example.DemoGraphQL.exception.GraphQLErrorAdapter;
import com.example.DemoGraphQL.repository.PersonRepository;
import com.example.DemoGraphQL.resolver.Query;
import com.example.DemoGraphQL.resolver.Mutation;
import graphql.ExceptionWhileDataFetching;
import graphql.GraphQLError;
import graphql.servlet.GraphQLErrorHandler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@SpringBootApplication
public class DemoGraphQlApplication {
public static void main(String[] args) {
SpringApplication.run(DemoGraphQlApplication.class, args);
}
@Bean
public GraphQLErrorHandler errorHandler() {
return new GraphQLErrorHandler() {
@Override
public List<GraphQLError> processErrors(List<GraphQLError> errors) {
List<GraphQLError> clientErrors = errors.stream()
.filter(this::isClientError)
.collect(Collectors.toList());
List<GraphQLError> serverErrors = errors.stream()
.filter(e -> !isClientError(e))
.map(GraphQLErrorAdapter::new)
.collect(Collectors.toList());
List<GraphQLError> e = new ArrayList<>();
e.addAll(clientErrors);
e.addAll(serverErrors);
return e;
}
protected boolean isClientError(GraphQLError error) {
return !(error instanceof ExceptionWhileDataFetching || error instanceof Throwable);
}
};
}
@Bean
public Query query(PersonRepository personRepository) {
return new Query(programRepository);
}
@Bean
public Mutation mutation(PersonRepository personRepository) {
return new Mutation(personRepository);
}
}
we are done with coding part.
STEPS
1) create a person.graphqls file with schema
2) connected to remote oracle db from application.properties
3) create a entity for table person matching the schema
4) implemented repository for the Entity
5) written the query and mutation resolver.
6) testing
navigate http://localhost:8080/graphiql
write the query:
{
getPerson(id:225) {
id,
name,
firstName,
lastName,
}
}
execute.
we are done.