[JAVA-14663] Update Graphql code for Boot 2.7.x changes and move to new module (#12729)
This commit is contained in:
parent
ae96297bc2
commit
c18ce8a0cf
|
@ -41,6 +41,7 @@
|
||||||
<module>spring-boot-environment</module>
|
<module>spring-boot-environment</module>
|
||||||
<module>spring-boot-exceptions</module>
|
<module>spring-boot-exceptions</module>
|
||||||
<module>spring-boot-flowable</module>
|
<module>spring-boot-flowable</module>
|
||||||
|
<module>spring-boot-graphql</module>
|
||||||
<module>spring-boot-groovy</module>
|
<module>spring-boot-groovy</module>
|
||||||
<!-- <module>spring-boot-gradle</module> --> <!-- Not a maven project -->
|
<!-- <module>spring-boot-gradle</module> --> <!-- Not a maven project -->
|
||||||
<module>spring-boot-jasypt</module>
|
<module>spring-boot-jasypt</module>
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"_postman_id": "bae0e3d0-2b86-46aa-b6df-523497a2296a",
|
||||||
|
"name": "GraphQL collection",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "mutations",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "createPost",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "graphql",
|
||||||
|
"graphql": {
|
||||||
|
"query": "mutation createPost ($title: String!, $text: String!, $category: String, $authorId: String!) {\n createPost (title: $title, text: $text, category: $category, authorId: $authorId) {\n id\n title\n text\n category\n }\n}",
|
||||||
|
"variables": "{\n \"title\": \"new post\",\n \"text\": \"new post text\",\n \"category\": \"category\",\n \"authorId\": \"Author0\"\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8080/graphql",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8080",
|
||||||
|
"path": [
|
||||||
|
"graphql"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "queries",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "get recent posts",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "graphql",
|
||||||
|
"graphql": {
|
||||||
|
"query": "{\r\n recentPosts(count: 10, offset: 0) {\r\n id\r\n title\r\n category\r\n text\r\n author {\r\n id\r\n name\r\n thumbnail\r\n }\r\n }\r\n}",
|
||||||
|
"variables": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8080/graphql",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8080",
|
||||||
|
"path": [
|
||||||
|
"graphql"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "recentPosts - variables",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "graphql",
|
||||||
|
"graphql": {
|
||||||
|
"query": "query recentPosts ($count: Int, $offset: Int) {\n recentPosts (count: $count, offset: $offset) {\n id\n title\n text\n category\n }\n}",
|
||||||
|
"variables": "{\n \"count\": 5,\n \"offset\": 0\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8080/graphql",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8080",
|
||||||
|
"path": [
|
||||||
|
"graphql"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"event": [
|
||||||
|
{
|
||||||
|
"listen": "prerequest",
|
||||||
|
"script": {
|
||||||
|
"type": "text/javascript",
|
||||||
|
"exec": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"listen": "test",
|
||||||
|
"script": {
|
||||||
|
"type": "text/javascript",
|
||||||
|
"exec": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"variable": [
|
||||||
|
{
|
||||||
|
"key": "url",
|
||||||
|
"value": "",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
## Spring Boot Graphql
|
||||||
|
|
||||||
|
This module contains articles about Spring Boot Graphql
|
||||||
|
|
||||||
|
### The Course
|
||||||
|
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Getting Started with GraphQL and Spring Boot](https://www.baeldung.com/spring-graphql)
|
||||||
|
- [Expose GraphQL Field with Different Name](https://www.baeldung.com/graphql-field-name)
|
||||||
|
|
||||||
|
### GraphQL sample queries
|
||||||
|
|
||||||
|
Query
|
||||||
|
```shell script
|
||||||
|
curl \
|
||||||
|
--request POST 'localhost:8080/graphql' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw '{"query":"query {\n recentPosts(count: 2, offset: 0) {\n id\n title\n author {\n id\n posts {\n id\n }\n }\n }\n}"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Mutation
|
||||||
|
```shell script
|
||||||
|
curl \
|
||||||
|
--request POST 'localhost:8080/graphql' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw '{"query":"mutation {\n createPost(title: \"New Title\", authorId: \"Author2\", text: \"New Text\") {\n id\n category\n author {\n id\n name\n }\n }\n}"}'
|
||||||
|
```
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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>
|
||||||
|
<artifactId>spring-boot-graphql</artifactId>
|
||||||
|
<name>spring-boot-graphql</name>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung.spring-boot-modules</groupId>
|
||||||
|
<artifactId>spring-boot-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-graphql</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.graphql</groupId>
|
||||||
|
<artifactId>spring-graphql-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Author {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String thumbnail;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
|
import org.springframework.graphql.data.method.annotation.SchemaMapping;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class AuthorController {
|
||||||
|
|
||||||
|
private final PostDao postDao;
|
||||||
|
|
||||||
|
public AuthorController(PostDao postDao) {
|
||||||
|
this.postDao = postDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SchemaMapping
|
||||||
|
public List<Post> posts(Author author) {
|
||||||
|
return postDao.getAuthorPosts(author.getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AuthorDao {
|
||||||
|
private final List<Author> authors;
|
||||||
|
|
||||||
|
public AuthorDao(List<Author> authors) {
|
||||||
|
this.authors = authors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Author getAuthor(String id) {
|
||||||
|
return authors.stream()
|
||||||
|
.filter(author -> id.equals(author.getId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(RuntimeException::new);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,16 @@
|
||||||
package com.baeldung.graphql;
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
import com.baeldung.graphql.GraphqlConfiguration;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@Import(GraphqlConfiguration.class)
|
|
||||||
@EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class})
|
@EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class})
|
||||||
public class DemoApplication {
|
public class GraphqlApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.setProperty("spring.config.name", "demo");
|
SpringApplication.run(GraphqlApplication.class, args);
|
||||||
SpringApplication.run(DemoApplication.class, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
package com.baeldung.graphql;
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class GraphqlConfiguration {
|
public class GraphqlConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public PostDao postDao() {
|
public PostDao postDao() {
|
||||||
List<Post> posts = new ArrayList<>();
|
List<Post> posts = new ArrayList<>();
|
||||||
|
@ -16,6 +17,7 @@ public class GraphqlConfiguration {
|
||||||
Post post = new Post();
|
Post post = new Post();
|
||||||
post.setId("Post" + authorId + postId);
|
post.setId("Post" + authorId + postId);
|
||||||
post.setTitle("Post " + authorId + ":" + postId);
|
post.setTitle("Post " + authorId + ":" + postId);
|
||||||
|
post.setCategory("Post category");
|
||||||
post.setText("Post " + postId + " + by author " + authorId);
|
post.setText("Post " + postId + " + by author " + authorId);
|
||||||
post.setAuthorId("Author" + authorId);
|
post.setAuthorId("Author" + authorId);
|
||||||
posts.add(post);
|
posts.add(post);
|
||||||
|
@ -36,24 +38,4 @@ public class GraphqlConfiguration {
|
||||||
}
|
}
|
||||||
return new AuthorDao(authors);
|
return new AuthorDao(authors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public PostResolver postResolver(AuthorDao authorDao) {
|
|
||||||
return new PostResolver(authorDao);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AuthorResolver authorResolver(PostDao postDao) {
|
|
||||||
return new AuthorResolver(postDao);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Query query(PostDao postDao) {
|
|
||||||
return new Query(postDao);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Mutation mutation(PostDao postDao) {
|
|
||||||
return new Mutation(postDao);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Post {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String title;
|
||||||
|
private String text;
|
||||||
|
private String category;
|
||||||
|
private String authorId;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
|
import org.springframework.graphql.data.method.annotation.Argument;
|
||||||
|
import org.springframework.graphql.data.method.annotation.MutationMapping;
|
||||||
|
import org.springframework.graphql.data.method.annotation.QueryMapping;
|
||||||
|
import org.springframework.graphql.data.method.annotation.SchemaMapping;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class PostController {
|
||||||
|
|
||||||
|
private final PostDao postDao;
|
||||||
|
private final AuthorDao authorDao;
|
||||||
|
|
||||||
|
public PostController(PostDao postDao, AuthorDao authorDao) {
|
||||||
|
this.postDao = postDao;
|
||||||
|
this.authorDao = authorDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
@QueryMapping
|
||||||
|
public List<Post> recentPosts(@Argument int count, @Argument int offset) {
|
||||||
|
return postDao.getRecentPosts(count, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SchemaMapping
|
||||||
|
public Author author(Post post) {
|
||||||
|
return authorDao.getAuthor(post.getAuthorId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SchemaMapping(typeName="Post", field="first_author")
|
||||||
|
public Author getFirstAuthor(Post post) {
|
||||||
|
return authorDao.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,21 +4,27 @@ import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PostDao {
|
public class PostDao {
|
||||||
private List<Post> posts;
|
|
||||||
|
private final List<Post> posts;
|
||||||
|
|
||||||
public PostDao(List<Post> posts) {
|
public PostDao(List<Post> posts) {
|
||||||
this.posts = posts;
|
this.posts = posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Post> getRecentPosts(int count, int offset) {
|
public List<Post> getRecentPosts(int count, int offset) {
|
||||||
return posts.stream().skip(offset).limit(count).collect(Collectors.toList());
|
return posts.stream()
|
||||||
|
.skip(offset)
|
||||||
|
.limit(count)
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Post> getAuthorPosts(String author) {
|
public List<Post> getAuthorPosts(String author) {
|
||||||
return posts.stream().filter(post -> author.equals(post.getAuthorId())).collect(Collectors.toList());
|
return posts.stream()
|
||||||
|
.filter(post -> author.equals(post.getAuthorId()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void savePost(Post post) {
|
public void savePost(Post post) {
|
||||||
posts.add(0, post);
|
posts.add(post);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
spring:
|
||||||
|
graphql:
|
||||||
|
graphiql:
|
||||||
|
enabled: true
|
|
@ -21,5 +21,5 @@ type Query {
|
||||||
|
|
||||||
# The Root Mutation for the application
|
# The Root Mutation for the application
|
||||||
type Mutation {
|
type Mutation {
|
||||||
writePost(title: String!, text: String!, category: String, author: String!) : Post!
|
createPost(title: String!, text: String!, category: String, authorId: String!) : Post!
|
||||||
}
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.graphql.GraphQlTest;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.graphql.test.tester.GraphQlTester;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
@GraphQlTest(PostController.class)
|
||||||
|
@Import(GraphqlConfiguration.class)
|
||||||
|
class PostControllerIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private GraphQlTester graphQlTester;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenPosts_whenExecuteQueryForRecentPosts_thenReturnResponse() {
|
||||||
|
String documentName = "recent_posts";
|
||||||
|
|
||||||
|
graphQlTester.documentName(documentName)
|
||||||
|
.variable("count", 2)
|
||||||
|
.variable("offset", 0)
|
||||||
|
.execute()
|
||||||
|
.path("$")
|
||||||
|
.matchesJson(expected(documentName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNewPostData_whenExecuteMutation_thenNewPostCreated() {
|
||||||
|
String documentName = "create_post";
|
||||||
|
|
||||||
|
graphQlTester.documentName(documentName)
|
||||||
|
.variable("title", "New Post")
|
||||||
|
.variable("text", "New post text")
|
||||||
|
.variable("category", "category")
|
||||||
|
.variable("authorId", "Author0")
|
||||||
|
.execute()
|
||||||
|
.path("createPost.id").hasValue()
|
||||||
|
.path("createPost.title").entity(String.class).isEqualTo("New Post")
|
||||||
|
.path("createPost.text").entity(String.class).isEqualTo("New post text")
|
||||||
|
.path("createPost.category").entity(String.class).isEqualTo("category");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static String expected(String fileName) {
|
||||||
|
Path path = Paths.get("src/test/resources/graphql-test/" + fileName + "_expected_response.json");
|
||||||
|
return new String(Files.readAllBytes(path));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.graphql;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest(classes = GraphqlApplication.class)
|
||||||
|
public class SpringContextTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,14 +9,14 @@
|
||||||
"name": "mutations",
|
"name": "mutations",
|
||||||
"item": [
|
"item": [
|
||||||
{
|
{
|
||||||
"name": "writePost",
|
"name": "createPost",
|
||||||
"request": {
|
"request": {
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"header": [],
|
"header": [],
|
||||||
"body": {
|
"body": {
|
||||||
"mode": "graphql",
|
"mode": "graphql",
|
||||||
"graphql": {
|
"graphql": {
|
||||||
"query": "mutation writePost ($title: String!, $text: String!, $category: String) {\n writePost (title: $title, text: $text, category: $category) {\n id\n title\n text\n category\n }\n}",
|
"query": "mutation createPost ($title: String!, $text: String!, $category: String) {\n createPost (title: $title, text: $text, category: $category) {\n id\n title\n text\n category\n }\n}",
|
||||||
"variables": "{\n \"title\": \"\",\n \"text\": \"\",\n \"category\": \"\"\n}"
|
"variables": "{\n \"title\": \"\",\n \"text\": \"\",\n \"category\": \"\"\n}"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
|
@ -0,0 +1,8 @@
|
||||||
|
mutation createPost ($title: String!, $text: String!, $category: String, $authorId: String!) {
|
||||||
|
createPost (title: $title, text: $text, category: $category, authorId: $authorId) {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
text
|
||||||
|
category
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
query recentPosts ($count: Int, $offset: Int) {
|
||||||
|
recentPosts (count: $count, offset: $offset) {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
text
|
||||||
|
category
|
||||||
|
author {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
thumbnail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"recentPosts": [
|
||||||
|
{
|
||||||
|
"id": "Post00",
|
||||||
|
"title": "Post 0:0",
|
||||||
|
"category": "Post category",
|
||||||
|
"text": "Post 0 + by author 0",
|
||||||
|
"author": {
|
||||||
|
"id": "Author0",
|
||||||
|
"name": "Author 0",
|
||||||
|
"thumbnail": "http://example.com/authors/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Post10",
|
||||||
|
"title": "Post 1:0",
|
||||||
|
"category": "Post category",
|
||||||
|
"text": "Post 0 + by author 1",
|
||||||
|
"author": {
|
||||||
|
"id": "Author1",
|
||||||
|
"name": "Author 1",
|
||||||
|
"thumbnail": "http://example.com/authors/1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,24 +13,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
- [Rate Limiting a Spring API Using Bucket4j](https://www.baeldung.com/spring-bucket4j)
|
- [Rate Limiting a Spring API Using Bucket4j](https://www.baeldung.com/spring-bucket4j)
|
||||||
- [Spring Boot and Caffeine Cache](https://www.baeldung.com/spring-boot-caffeine-cache)
|
- [Spring Boot and Caffeine Cache](https://www.baeldung.com/spring-boot-caffeine-cache)
|
||||||
- [Spring Boot and Togglz Aspect](https://www.baeldung.com/spring-togglz)
|
- [Spring Boot and Togglz Aspect](https://www.baeldung.com/spring-togglz)
|
||||||
- [Getting Started with GraphQL and Spring Boot](https://www.baeldung.com/spring-graphql)
|
- More articles: [[next -->]](../spring-boot-libraries-2)
|
||||||
- [Expose GraphQL Field with Different Name](https://www.baeldung.com/graphql-field-name)
|
|
||||||
- More articles: [[next -->]](/spring-boot-modules/spring-boot-libraries-2)
|
|
||||||
|
|
||||||
### GraphQL sample queries
|
|
||||||
|
|
||||||
Query
|
|
||||||
```shell script
|
|
||||||
curl \
|
|
||||||
--request POST 'localhost:8081/graphql' \
|
|
||||||
--header 'Content-Type: application/json' \
|
|
||||||
--data-raw '{"query":"query {\n recentPosts(count: 2, offset: 0) {\n id\n title\n author {\n id\n posts {\n id\n }\n }\n }\n}"}'
|
|
||||||
```
|
|
||||||
|
|
||||||
Mutation
|
|
||||||
```shell script
|
|
||||||
curl \
|
|
||||||
--request POST 'localhost:8081/graphql' \
|
|
||||||
--header 'Content-Type: application/json' \
|
|
||||||
--data-raw '{"query":"mutation {\n writePost(title: \"New Title\", author: \"Author2\", text: \"New Text\") {\n id\n category\n author {\n id\n name\n }\n }\n}"}'
|
|
||||||
```
|
|
||||||
|
|
|
@ -46,22 +46,6 @@
|
||||||
<artifactId>togglz-spring-security</artifactId>
|
<artifactId>togglz-spring-security</artifactId>
|
||||||
<version>${togglz.version}</version>
|
<version>${togglz.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- graphql -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.graphql-java</groupId>
|
|
||||||
<artifactId>graphql-spring-boot-starter</artifactId>
|
|
||||||
<version>${graphql-spring-boot-starter.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.graphql-java</groupId>
|
|
||||||
<artifactId>graphql-java-tools</artifactId>
|
|
||||||
<version>${graphql-java-tools.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.graphql-java</groupId>
|
|
||||||
<artifactId>graphiql-spring-boot-starter</artifactId>
|
|
||||||
<version>${graphql-spring-boot-starter.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- Problem Spring Web -->
|
<!-- Problem Spring Web -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.zalando</groupId>
|
<groupId>org.zalando</groupId>
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
package com.baeldung.graphql;
|
|
||||||
|
|
||||||
public class Author {
|
|
||||||
private String id;
|
|
||||||
private String name;
|
|
||||||
private String thumbnail;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getThumbnail() {
|
|
||||||
return thumbnail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThumbnail(String thumbnail) {
|
|
||||||
this.thumbnail = thumbnail;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package com.baeldung.graphql;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class AuthorDao {
|
|
||||||
private List<Author> authors;
|
|
||||||
|
|
||||||
public AuthorDao(List<Author> authors) {
|
|
||||||
this.authors = authors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<Author> getAuthor(String id) {
|
|
||||||
return authors.stream().filter(author -> id.equals(author.getId())).findFirst();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package com.baeldung.graphql;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.coxautodev.graphql.tools.GraphQLResolver;
|
|
||||||
|
|
||||||
public class AuthorResolver implements GraphQLResolver<Author> {
|
|
||||||
private PostDao postDao;
|
|
||||||
|
|
||||||
public AuthorResolver(PostDao postDao) {
|
|
||||||
this.postDao = postDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Post> getPosts(Author author) {
|
|
||||||
return postDao.getAuthorPosts(author.getId());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.baeldung.graphql;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import com.coxautodev.graphql.tools.GraphQLMutationResolver;
|
|
||||||
|
|
||||||
public class Mutation implements GraphQLMutationResolver {
|
|
||||||
private PostDao postDao;
|
|
||||||
|
|
||||||
public Mutation(PostDao postDao) {
|
|
||||||
this.postDao = postDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Post writePost(String title, String text, String category, String author) {
|
|
||||||
Post post = new Post();
|
|
||||||
post.setId(UUID.randomUUID().toString());
|
|
||||||
post.setTitle(title);
|
|
||||||
post.setText(text);
|
|
||||||
post.setCategory(category);
|
|
||||||
post.setAuthorId(author);
|
|
||||||
postDao.savePost(post);
|
|
||||||
|
|
||||||
return post;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package com.baeldung.graphql;
|
|
||||||
|
|
||||||
public class Post {
|
|
||||||
private String id;
|
|
||||||
private String title;
|
|
||||||
private String text;
|
|
||||||
private String category;
|
|
||||||
private String authorId;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCategory() {
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCategory(String category) {
|
|
||||||
this.category = category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthorId() {
|
|
||||||
return authorId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthorId(String authorId) {
|
|
||||||
this.authorId = authorId;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.baeldung.graphql;
|
|
||||||
|
|
||||||
import com.coxautodev.graphql.tools.GraphQLResolver;
|
|
||||||
|
|
||||||
public class PostResolver implements GraphQLResolver<Post> {
|
|
||||||
private AuthorDao authorDao;
|
|
||||||
|
|
||||||
public PostResolver(AuthorDao authorDao) {
|
|
||||||
this.authorDao = authorDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Author getAuthor(Post post) {
|
|
||||||
return authorDao.getAuthor(post.getAuthorId()).orElseThrow(RuntimeException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Author getFirst_author(Post post) {
|
|
||||||
return authorDao.getAuthor(post.getAuthorId()).orElseThrow(RuntimeException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package com.baeldung.graphql;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
|
|
||||||
|
|
||||||
public class Query implements GraphQLQueryResolver {
|
|
||||||
private PostDao postDao;
|
|
||||||
|
|
||||||
public Query(PostDao postDao) {
|
|
||||||
this.postDao = postDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Post> getRecentPosts(int count, int offset) {
|
|
||||||
return postDao.getRecentPosts(count, offset);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue