In this
post, I am going to explain how to setup a spring boot GraphQL project and
experiment with it.
Step 1:
Create new maven
project ‘springbootGraphQL’.
Step 2:
Update pom.xml with
graphql and springboot dependencies.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springbootGraphQL</groupId>
<artifactId>springbootGraphQL</artifactId>
<version>1</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<name>springbootApp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>5.0.2</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>5.2.4</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>5.0.2</version>
</dependency>
</dependencies>
</project>
I am using H2 in memory database to store the data.
Step 3:
Create entity classes
(Employee, Address, Department).
Department.java
package com.sample.app.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "department")
public class Department {
@Id
@GeneratedValue
private long id;
private String departmentName;
public Department() {
this("none");
}
public Department(String departmentName) {
super();
this.departmentName = departmentName;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Department [id=").append(id).append(", departmentName=").append(departmentName).append("]");
return builder.toString();
}
}
Address.java
package com.sample.app.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "address")
public class Address {
@Id
@GeneratedValue
private long id;
private String city;
private String state;
private String country;
public Address() {
this("none", "none", "none");
}
public Address(String city, String state, String country) {
super();
this.city = city;
this.state = state;
this.country = country;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Address [id=").append(id).append(", city=").append(city).append(", state=").append(state)
.append(", country=").append(country).append("]");
return builder.toString();
}
}
Employee.java
package com.sample.app.entity;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue
private long id;
private String firstName;
private String lastName;
private String email;
@OneToOne(cascade = CascadeType.ALL)
private Address permanentAddress;
@OneToOne(cascade = CascadeType.ALL)
private Address temporaryAddress;
@OneToOne(cascade = CascadeType.ALL)
private Department department;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
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;
}
public Address getPermanentAddress() {
return permanentAddress;
}
public void setPermanentAddress(Address permanentAddress) {
this.permanentAddress = permanentAddress;
}
public Address getTemporaryAddress() {
return temporaryAddress;
}
public void setTemporaryAddress(Address temporaryAddress) {
this.temporaryAddress = temporaryAddress;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Employee [id=").append(id).append(", firstName=").append(firstName).append(", lastName=")
.append(lastName).append(", email=").append(email).append(", permanentAddress=")
.append(permanentAddress).append(", temporaryAddress=").append(temporaryAddress).append(", department=")
.append(department).append("]");
return builder.toString();
}
public static EmployeeBuilder builder() {
return new EmployeeBuilder();
}
public static class EmployeeBuilder {
Employee emp;
public EmployeeBuilder() {
emp = new Employee();
emp.setPermanentAddress(new Address());
emp.setTemporaryAddress(new Address());
emp.setDepartment(new Department());
}
public Employee build() {
return emp;
}
public EmployeeBuilder firstName(String firstName) {
emp.setFirstName(firstName);
return this;
}
public EmployeeBuilder lastName(String lastName) {
emp.setLastName(lastName);
return this;
}
public EmployeeBuilder email(String email) {
emp.setEmail(email);
return this;
}
public EmployeeBuilder permanentAddress(Address permanentAddress) {
emp.setPermanentAddress(permanentAddress);
return this;
}
public EmployeeBuilder temporaryAddress(Address temporaryAddress) {
emp.setTemporaryAddress(temporaryAddress);
return this;
}
public EmployeeBuilder department(Department department) {
emp.setDepartment(department);
return this;
}
}
}
Step 4:
Create EmployeeRepository
interface.
package com.sample.app.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.sample.app.entity.Employee;
@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
}
Step 5:
Create QueryResolver
class which implements GraphQLQueryResolver interface.
package com.sample.app.resolvers;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import com.sample.app.entity.Employee;
import com.sample.app.repository.EmployeeRepository;
@Component
public class QueryResolver implements GraphQLQueryResolver {
@Autowired
public EmployeeRepository empRepo;
public List<Employee> employees() {
List<Employee> emps = new ArrayList<>();
Iterable<Employee> empsIterable = empRepo.findAll();
for (Employee emp : empsIterable) {
emps.add(emp);
}
return emps;
}
}
Step 6:
Create main
application class.
App.java
package com.sample.app;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.sample.app.entity.Address;
import com.sample.app.entity.Department;
import com.sample.app.entity.Employee;
import com.sample.app.repository.EmployeeRepository;
@SpringBootApplication
public class App {
@Autowired
public EmployeeRepository empRepo;
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Bean
public CommandLineRunner demo() {
return (args) -> {
Employee emp1 = Employee.builder().firstName("ram").lastName("Gurram").email("krishna@abc.com")
.permanentAddress(new Address("Bangalore", "Karnataka", "India"))
.temporaryAddress(new Address("Hyderabad", "Telangana", "India"))
.department(new Department("Infrastructure Services")).build();
Employee emp2 = Employee.builder().firstName("Joel").lastName("Chelli").email("joel@abc.com")
.permanentAddress(new Address("Chennai", "Tamilnadu", "India"))
.temporaryAddress(new Address("Hyderabad", "Telangana", "India"))
.department(new Department("Core Systems")).build();
Employee emp3 = Employee.builder().firstName("Gopi").lastName("Battu").email("gopi@abc.com")
.permanentAddress(new Address("Bangalore", "Karnataka", "India"))
.temporaryAddress(new Address("Chennai", "Tamilnadu", "India"))
.department(new Department("Infrastructure Services")).build();
empRepo.saveAll(Arrays.asList(emp1, emp2, emp3));
};
}
}
Configurations
Create
application.propeties file under src/main/resources folder
application.properties
logging.level.root=WARN logging.level.org.hibernate=ERROR ## H2 specific properties spring.h2.console.enabled=true spring.h2.console.path=/h2 spring.datasource.url=jdbc:h2:file:~/db/myOrg.db;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1; spring.datasource.username=krishna spring.datasource.password=password123 spring.datasource.driverClassName=org.h2.Driver ## JPA specific properties # Creates the schema, destroying previous data. spring.jpa.hibernate.ddl-auto=create spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true ## Database connection pooling properties # Number of ms to wait before throwing an exception if no connection is available. spring.datasource.max-wait=10000 # Maximum number of active connections that can be allocated from this pool at the same time. spring.datasource.tomcat.max-active=10 spring.datasource.tomcat.max-idle=5 spring.datasource.tomcat.min-idle=3 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true # Used to trace the transaction behavior logging.level.org.springframework.transaction.interceptor=TRACE
Create ‘employees.graphqls’
file that define the definition of types and queries.
employees.graphqls
type Query { employees: [Employee] } type Employee { id: Int firstName: String lastName: String email: String permanentAddress: Address temporaryAddress: Address department: Department } type Address { id: Int city: String state: String country: String } type Department{ id: Int departmentName: String }
Total
project structure looks like below.
Run
App.java.
Open the
url ‘http://localhost:8080/graphiql’ in browser, you can see below kind of
screen.
On left
side of window add below graphQL payload.
{ employees { firstName email } }
Click on
Play button.
You can
see below response.
{ "data": { "employees": [ { "firstName": "ram", "email": "krishna@abc.com" }, { "firstName": "Joel", "email": "joel@abc.com" }, { "firstName": "Gopi", "email": "gopi@abc.com" } ] } }
If you
want lastName, and city field of permanentAddress too, you can construct query like
below.
{ employees { firstName email lastName permanentAddress{ city } } }
You will
receive below response.
{ "data": { "employees": [ { "firstName": "ram", "email": "krishna@abc.com", "lastName": "Gurram", "permanentAddress": { "city": "Bangalore" } }, { "firstName": "Joel", "email": "joel@abc.com", "lastName": "Chelli", "permanentAddress": { "city": "Chennai" } }, { "firstName": "Gopi", "email": "gopi@abc.com", "lastName": "Battu", "permanentAddress": { "city": "Bangalore" } } ] } }
You can
download complete working application from this link.
No comments:
Post a Comment