Spring GraphQL
https://github.com/spring-boot-tutorials/spring-graphql
In this article we will configure Spring Boot to serve GraphQL endpoints.
Create Initial Code Base
Go to https://start.spring.io/
Add the following dependencies:
spring-boot-starter-graphql
spring-boot-starter-web
lombok
Click Generate
Dependencies
Dependencies used in pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
Properties
Add the following properties into src/main/resources/application.yaml
:
spring:
graphql:
graphiql:
# enables GraphQL UI at http://localhost:8080/graphiql
enabled: true
GraphQL Schema Files
Create new file src/main/resources/graphql/start.gqls
:
type Post {
id: ID!
title: String!
text: String!
category: String
author: Author!
}
type Author {
id: ID!
name: String!
thumbnail: String
posts: [Post]!
}
# The Root Query for the application
type Query {
recentPosts(count: Int, offset: Int): [Post]!
}
# The Root Mutation for the application
type Mutation {
createPost(title: String!, text: String!, category: String, authorId: String!) : Post!
}
Model
Let’s create a new POJO src/main/java/com/example/graphql/model/Author.java
@Data
@SuperBuilder
@NoArgsConstructor
public class Author {
private String id;
private String name;
private String thumbnail;
private List<Post> posts;
}
Create a new POJO src/main/java/com/example/graphql/model/Post.java
:
@Data
@SuperBuilder
@NoArgsConstructor
public class Post {
private String id;
private String title;
private String category;
private String authorId;
private String text;
}
Repository
Create a stub repository with fake data src/main/java/com/example/graphql/repository/PostRepository.java
:
@Service
public class PostRepository {
private List<Post> posts = new ArrayList<>();
private List<Author> authors = new ArrayList<>();
public PostRepository() {
posts.add(Post.builder()
.id("id-1")
.title("title-1")
.authorId("author-1")
.text("text-1")
.category("category-1")
.build());
posts.add(Post.builder()
.id("id-2")
.title("title-2")
.authorId("author-2")
.text("text-2")
.category("category-2")
.build());
posts.add(Post.builder()
.id("id-3")
.title("title-3")
.authorId("author-3")
.text("text-3")
.category("category-3")
.build());
authors.add(Author.builder()
.id("author-1")
.name("name-1")
.thumbnail("thumbnail-1")
.posts(List.of(posts.get(0)))
.build());
authors.add(Author.builder()
.id("author-2")
.name("name-2")
.thumbnail("thumbnail-2")
.posts(List.of(posts.get(1)))
.build());
authors.add(Author.builder()
.id("author-3")
.name("name-3")
.thumbnail("thumbnail-3")
.posts(List.of(posts.get(2)))
.build());
}
public List<Post> getRecentPosts() {
return this.posts;
}
public void savePost(Post post) {
this.posts.add(post);
}
public Author getAuthor(String authorID) {
return authors.stream()
.filter(a -> a.getId().equals(authorID)).findFirst()
.orElse(null);
}
}
Controller
Create a new class src/main/java/com/example/graphql/controller/PostController.java
:
@Controller
public class PostController {
@Autowired
private PostRepository postDao;
@QueryMapping
public List<Post> recentPosts(@Argument int count, @Argument int offset) {
return postDao.getRecentPosts();
}
@SchemaMapping
public Author author(Post post) {
return postDao.getAuthor(post.getAuthorId());
}
@MutationMapping
public Post createPost(@Argument String title,
@Argument String text,
@Argument String category,
@Argument String authorId) {
Post post = new Post();
post.setId(UUID.randomUUID().toString());
post.setTitle(title);
post.setText(text);
post.setCategory(category);
post.setAuthorId(authorId);
postDao.savePost(post);
return post;
}
}
Run & Verify Application
Open terminal at project root and execute the following:
mvn spring-boot:run
Goto: http://localhost:8080/graphiql
Input GraphQL Query:
query {
recentPosts(count: 10, offset: 0) {
id
title
category
author {
id
name
thumbnail
}
}
}