开发人员会仔细研究一些JavaXML代码,这些代码用于创建使用GraphQL来获取数据的基本微服务应用程序。

GraphQLFacebook发明和开源的一种API,可以更好地替代REST。可以将其理解为用于APIQuerby语言,它可以通过公开单个端点并响应查询来进行声明式数据获取。在REST中,每种类型的请求总有一个专用端点,并且无法自定义。

GraphQL中,客户端决定所需的数据,这就是客户端向服务器发送查询(有效负载),然后服务器根据查询请求将数据发送回的原因。他们在哪里获得名称GraphQL

优锐课带大家看一个例子来了解技术细节。在此示例中,我们将使用graphQL构建一个简单的书店应用程序。

pom.xml

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

    4.0.0

    com.dugu.acc.dev

    spring-graphql

    0.0.1-SNAPSHOT

    jar

    spring-graphql

    GraphQL is invented by Facebook as a better replacement of REST for Web APIs

   

        org.springframework.boot

        spring-boot-starter-parent

        1.5.9.RELEASE

        />

   

   

        UTF-8

        UTF-8

        1.8

   

   

       

            org.springframework.boot

            spring-boot-starter-data-jpa

       

       

            org.springframework.boot

            spring-boot-starter-web

       

        

            org.springframework.boot

            spring-boot-devtools

            runtime

       

       

            com.h2database

            h2

            runtime

       

       

            org.projectlombok

            lombok

            true

       

       

            com.graphql-java

            graphql-spring-boot-starter

            3.6.0

       

       

            com.graphql-java

            graphql-java-tools

            3.2.0

       

       

            org.springframework.boot

            spring-boot-starter-test

            test

       

   

   

       

           

                org.springframework.boot

                spring-boot-maven-plugin

           

       

   


GraphQL模式是GraphQL的主要概念,它基于SDL(模式定义语言)。我们可以定义简单的类型,如下面的示例中所示,我们可以看到“类型Book”,以及它们之间的关系(例如,“类型查询”与Book有关系)。这种关系可以是一对一,一对多,多对一和多对多。在下面的示例中,“类型查询”具有一对多(allBooks)和一对一(Book)关系。模式在获取数据方面起着主要作用。

下面的文件位于我的GitHub存储库的src/main/resource文件夹下(如本文结尾所示)。

book.schema

schema{

query: Query

  }

type Query{

allBooks: [Book]

Book(id: String): Book

 }

type Book{

bookId: String

bookName: String

publishedDate: String

writer: [String]

publisher: String

}

 

BookSearchController.java

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;

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

import org.springframework.core.io.Resource;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

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

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

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

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

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

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

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

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

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

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

import graphql.ExecutionResult;

import graphql.GraphQL;

import graphql.schema.GraphQLSchema;

import graphql.schema.idl.RuntimeWiring;

import graphql.schema.idl.SchemaGenerator;

import graphql.schema.idl.SchemaParser;

import graphql.schema.idl.TypeDefinitionRegistry;

@RestController

@RequestMapping("/bookstore")

public class BookSearchController {

 @Autowired

 private BookService service;

 // load graphqls file

 @Value("classpath:book.schema")

 private Resource schemaResource;

 @Autowired

 private AllBookDataFetcher allBookDataFetcher;

 @Autowired

 private BookDataFetcher bookDataFetcher;

 private GraphQL graphQL;

 // load schema at application start up

 @PostConstruct

 public void loadSchema() throws IOException {

  // get the schema

  File schemaFile = schemaResource.getFile();

  // parse schema

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

  RuntimeWiring wiring = buildRuntimeWiring();

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

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

 }

 private RuntimeWiring buildRuntimeWiring() {

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

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

 }

 @GetMapping("/booksList")

 public List < Book > getBooksList() {

  return service.findAllBooks();

 }

 /*

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

  * and Body: query{

   allBooks{

 bookId,

 bookName

   }

 }

  */

 @PostMapping("/getAllBooks")

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

  ExecutionResult result = graphQL.execute(query);

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

 }

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

 public Book getBookInfo(@PathVariable String movieId) {

  return service.findBookById(movieId);

 }

 @PostMapping("/getBookById")

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

  ExecutionResult result = graphQL.execute(query);

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

 }

}

 

AllBookDataFetcher.java

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;

import graphql.schema.DataFetcher;

import graphql.schema.DataFetchingEnvironment;

@Component

public class AllBookDataFetcher implements DataFetcher < List < Book >> {

 @Autowired

 private BookRepository repository;

 @Override

 public List < Book > get(DataFetchingEnvironment environment) {

  return repository.findAll();

 }

}

 

BookDataFetcher.java

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

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;

import graphql.schema.DataFetcher;

import graphql.schema.DataFetchingEnvironment;

@Component

public class BookDataFetcher implements DataFetcher < Book > {

 @Autowired

 private BookRepository repository;

 @Override

 public Book get(DataFetchingEnvironment environment) {

  String movieId = environment.getArgument("id");

  return repository.findOne(movieId);

 }

}

 

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;

@ToString

@AllArgsConstructor

@NoArgsConstructor

@Table

@Entity

public class Book {

 @Id

 private String bookId;

 private String bookName;

 private String publishedDate;

 private String[] writer;

 private String publisher;

}

 

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, String> {

}

 

BookService.java

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

import java.util.*;

import javax.annotation.PostConstruct;

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

import org.springframework.stereotype.Service;

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

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

@Service

public class BookService {

 @Autowired

 private BookRepository repository;

 @PostConstruct

 public void initBooks() {

  List < Book > books = new ArrayList < > ();

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

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

    "Sebastian"

   },

   "Infinity Stones"));

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

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

    "Sebastian",

    "Elizabeth"

   },

   "Infinity Stones"));

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

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

    "Sebastian"

   },

   "Infinity Stones"));

  repository.save(books);

 }

 public List < Book > findAllBooks() {

  return repository.findAll();

 }

 public Book findBookById(String movieId) {

  return repository.findOne(movieId);

 }

}

 

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) {

  SpringApplication.run(SpringGraphqlApplication.class, args);

 }

}

启动SpringGraphqlApplication,然后使用邮递员如下所示调用GraphQL端点:

Postman中,使用Post URLlocalhost:8080/bookstore/getAllBooks 

和正文:query{ allBooks{bookId,bookName }} 

你可以在主体部分中添加更多字段,因此,它将从服务器检索数据。

这就是本次演讲的全部内容。感受GraphQL的强大功能。