0% found this document useful (0 votes)
7 views25 pages

Microservices With GraphQL

The document discusses the use of GraphQL as a modern alternative to REST for API development, emphasizing its ability to allow clients to specify the data they need through a single endpoint. It provides a detailed example of building a simple bookstore application using GraphQL, including the necessary code for setting up the project and defining the GraphQL schema. The document also includes instructions for testing the application using Postman and links to a GitHub repository for further reference.

Uploaded by

Giuseppe Celano
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views25 pages

Microservices With GraphQL

The document discusses the use of GraphQL as a modern alternative to REST for API development, emphasizing its ability to allow clients to specify the data they need through a single endpoint. It provides a detailed example of building a simple bookstore application using GraphQL, including the necessary code for setting up the project and defining the GraphQL schema. The document also includes instructions for testing the application using Postman and links to a GitHub repository for further reference.

Uploaded by

Giuseppe Celano
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

Microservices With GraphQL

dzone.com/articles/microservices-with-graphql

Like (17)
Comment (6)

Save

Tweet
GraphQL is an API that was invented and open sourced by Facebook as a better
replacement for REST. It can be understood as Querby language for APIs, which enables
declarative data fetching by exposing a single endpoint and responds to queries. In REST,
there is always a dedicated endpoint for each type of request and can't be customized.

In GraphQL, the client decides what data they need and that's the reason the client sends
a query (payload) to the server and the server sends the data back as per the query
request. There is where they get the name GraphQL

Let's look at an example to understand the technical details. In this example, we will build
a simple book store application using graphQL.

pom.xml

<?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>

<groupId>com.dugu.acc.dev</groupId>

<artifactId>spring-graphql</artifactId>

<version>0.0.1-SNAPSHOT</version>

1/25
<packaging>jar</packaging>

<name>spring-graphql</name>

<description>GraphQL is invented by Facebook as a better replacement of REST


for Web APIs</description>

10

<parent>

11

<groupId>org.springframework.boot</groupId>

12

<artifactId>spring-boot-starter-parent</artifactId>

13

<version>1.5.9.RELEASE</version>

14

<relativePath />

15

</parent>

16

<properties>

17

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

18

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

19

<java.version>1.8</java.version>

20

</properties>

21

2/25
<dependencies>

22

<dependency>

23

<groupId>org.springframework.boot</groupId>

24

<artifactId>spring-boot-starter-data-jpa</artifactId>

25

</dependency>

26

<dependency>

27

<groupId>org.springframework.boot</groupId>

28

<artifactId>spring-boot-starter-web</artifactId>

29

</dependency>

30

<dependency>

31

<groupId>org.springframework.boot</groupId>

32

<artifactId>spring-boot-devtools</artifactId>

33

<scope>runtime</scope>

34

</dependency>

35

3/25
<dependency>

36

<groupId>com.h2database</groupId>

37

<artifactId>h2</artifactId>

38

<scope>runtime</scope>

39

</dependency>

40

<dependency>

41

<groupId>org.projectlombok</groupId>

42

<artifactId>lombok</artifactId>

43

<optional>true</optional>

44

</dependency>

45

<dependency>

46

<groupId>com.graphql-java</groupId>

47

<artifactId>graphql-spring-boot-starter</artifactId>

48

<version>3.6.0</version>

49

4/25
</dependency>

50

<dependency>

51

<groupId>com.graphql-java</groupId>

52

<artifactId>graphql-java-tools</artifactId>

53

<version>3.2.0</version>

54

</dependency>

55

<dependency>

56

<groupId>org.springframework.boot</groupId>

57

<artifactId>spring-boot-starter-test</artifactId>

58

<scope>test</scope>

59

</dependency>

60

</dependencies>

61

<build>

62

<plugins>

63

5/25
<plugin>

64

<groupId>org.springframework.boot</groupId>

65

<artifactId>spring-boot-maven-plugin</artifactId>

66

</plugin>

67

</plugins>

68

</build>

69

</project>

The GraphQL schema is the main concept of GraphQL, which is based on SDL (Schema
Definition language). We can define the simple types as we can see 'type Book' in below
example, and relations as well (for example, 'type Query' has a relation with Book). The
relationship could be one to one, one to many, many to one, and many to many. In the
below example, 'type Query' has a one to many (allBooks) and a one to one (Book)
relationship. The schema is playing the major role to fetch the data.

The below file is under the src/main/resource folder of my GitHub repo (liked to at the
end of the article).

book.schema

schema{

query: Query

6/25
5

type Query{

allBooks: [Book]

Book(id: String): Book

10

11

type Book{

12

bookId: String

13

bookName: String

14

publishedDate: String

15

writer: [String]

16

publisher: String

17

BookSearchController.java

7/25
1

package com.arun.spring.graphql.api.controller;

import java.io.File;

import java.io.IOException;

import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;

10

import org.springframework.beans.factory.annotation.Value;

11

import org.springframework.core.io.Resource;

12

import org.springframework.http.HttpStatus;

13

import org.springframework.http.ResponseEntity;

14

import org.springframework.web.bind.annotation.GetMapping;

8/25
15

import org.springframework.web.bind.annotation.PathVariable;

16

import org.springframework.web.bind.annotation.PostMapping;

17

import org.springframework.web.bind.annotation.RequestBody;

18

import org.springframework.web.bind.annotation.RequestMapping;

19

import org.springframework.web.bind.annotation.RestController;

20

21

import com.arun.spring.graphql.api.datafetcher.BookDataFetcher;

22

import com.arun.spring.graphql.api.datafetcher.AllBookDataFetcher;

23

import com.arun.spring.graphql.api.entity.Book;

24

import com.arun.spring.graphql.api.service.BookService;

25

26

import graphql.ExecutionResult;

27

import graphql.GraphQL;

28

import graphql.schema.GraphQLSchema;

9/25
29

import graphql.schema.idl.RuntimeWiring;

30

import graphql.schema.idl.SchemaGenerator;

31

import graphql.schema.idl.SchemaParser;

32

import graphql.schema.idl.TypeDefinitionRegistry;

33

34

@RestController

35

@RequestMapping("/bookstore")

36

public class BookSearchController {

37

@Autowired

38

private BookService service;

39

// load graphqls file

40

@Value("classpath:book.schema")

41

private Resource schemaResource;

42

@Autowired

10/25
43

private AllBookDataFetcher allBookDataFetcher;

44

@Autowired

45

private BookDataFetcher bookDataFetcher;

46

47

private GraphQL graphQL;

48

49

// load schema at application start up

50

@PostConstruct

51

public void loadSchema() throws IOException {

52

// get the schema

53

File schemaFile = schemaResource.getFile();

54

// parse schema

55

TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(schemaFile);

56

RuntimeWiring wiring = buildRuntimeWiring();

11/25
57

GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(typeRegistry,


wiring);

58

graphQL = GraphQL.newGraphQL(schema).build();

59

60

61

private RuntimeWiring buildRuntimeWiring() {

62

return RuntimeWiring.newRuntimeWiring().type("Query", typeWiring -> typeWiring

63

.dataFetcher("allBooks", allBookDataFetcher).dataFetcher("book",
bookDataFetcher)).build();

64

65

66

@GetMapping("/booksList")

67

public List < Book > getBooksList() {

68

return service.findAllBooks();

69

70

12/25
71

/*

72

* In PostMan use Post URL: localhost:8080/bookstore/getAllBooks

73

* and Body: query{

74

allBooks{

75

bookId,

76

bookName

77

78

79

*/

80

@PostMapping("/getAllBooks")

81

public ResponseEntity < Object > getAllBooks(@RequestBody String query) {

82

ExecutionResult result = graphQL.execute(query);

83

return new ResponseEntity < Object > (result, HttpStatus.OK);

84

13/25
}

85

86

@GetMapping("/search/{bookId}")

87

public Book getBookInfo(@PathVariable String movieId) {

88

return service.findBookById(movieId);

89

90

91

@PostMapping("/getBookById")

92

public ResponseEntity < Object > getBookById(@RequestBody String query) {

93

ExecutionResult result = graphQL.execute(query);

94

return new ResponseEntity < Object > (result, HttpStatus.OK);

95

96

AllBookDataFetcher.java

14/25
package com.arun.spring.graphql.api.datafetcher;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import com.arun.spring.graphql.api.entity.Book;

import com.arun.spring.graphql.api.repository.BookRepository;

10

11

import graphql.schema.DataFetcher;

12

import graphql.schema.DataFetchingEnvironment;

13

14

@Component

15

15/25
public class AllBookDataFetcher implements DataFetcher < List < Book >> {

16

@Autowired

17

private BookRepository repository;

18

19

@Override

20

public List < Book > get(DataFetchingEnvironment environment) {

21

return repository.findAll();

22

23

BookDataFetcher.java

package com.arun.spring.graphql.api.datafetcher;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

16/25
6

import com.arun.spring.graphql.api.entity.Book;

import com.arun.spring.graphql.api.repository.BookRepository;

import graphql.schema.DataFetcher;

10

import graphql.schema.DataFetchingEnvironment;

11

12

@Component

13

public class BookDataFetcher implements DataFetcher < Book > {

14

@Autowired

15

private BookRepository repository;

16

17

@Override

18

public Book get(DataFetchingEnvironment environment) {

19

17/25
String movieId = environment.getArgument("id");

20

return repository.findOne(movieId);

21

22

Book.java

package com.arun.spring.graphql.api.entity;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.Table;

import lombok.AllArgsConstructor;

import lombok.NoArgsConstructor;

import lombok.ToString;

10

18/25
11

@ToString

12

@AllArgsConstructor

13

@NoArgsConstructor

14

@Table

15

@Entity

16

public class Book {

17

@Id

18

private String bookId;

19

private String bookName;

20

private String publishedDate;

21

private String[] writer;

22

private String publisher;

23

19/25
BookRepository.java

package com.arun.spring.graphql.api.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.arun.spring.graphql.api.entity.Book;

public interface BookRepository extends JpaRepository<Book, String> {

BookService.java

package com.arun.spring.graphql.api.service;

import java.util.*;

20/25
import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.arun.spring.graphql.api.entity.Book;

10

import com.arun.spring.graphql.api.repository.BookRepository;

11

12

@Service

13

public class BookService {

14

@Autowired

15

private BookRepository repository;

16

17

@PostConstruct

18

public void initBooks() {

19

21/25
List < Book > books = new ArrayList < > ();

20

books.add(new Book("101", "The Science of Marvel",

21

"22-12-2017", new String[] {

22

"Sebastian"

23

},

24

"Infinity Stones"));

25

books.add(new Book("102", "The Sixth Extinction",

26

"22-12-2017", new String[] {

27

"Sebastian",

28

"Elizabeth"

29

},

30

"Infinity Stones"));

31

books.add(new Book("103", "The Science of Marvel -2",

32

"22-12-2019", new String[] {

33

22/25
"Sebastian"

34

},

35

"Infinity Stones"));

36

repository.save(books);

37

38

39

public List < Book > findAllBooks() {

40

return repository.findAll();

41

42

43

public Book findBookById(String movieId) {

44

return repository.findOne(movieId);

45

46

23/25
SpringGraphqlApplication.java

package com.arun.spring.graphql.api;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class SpringGraphqlApplication {

public static void main(String[] args) {

10

SpringApplication.run(SpringGraphqlApplication.class, args);

11

12

Start the SpringGraphqlApplication and then call the GraphQL endpoint as shown below
using Postman:

In Postman, use the Post URL: localhost:8080/bookstore/getAllBooks


and Body: query{ allBooks{bookId,bookName }}

24/25
You can add more fields in the body part and, accordingly, it will retrieve the data from
server.

That's all for this talk. Enjoy the power of GraphQL.

GitHub URL:
https://github.com/arunpandeycdac/MicroserviceWithSpringBootAndGraphQL

Topics:

java, microservice, graphql, microservices tutorial java

Opinions expressed by DZone contributors are their own.

25/25

You might also like