开发人员会仔细研究一些Java和XML代码,这些代码用于创建使用GraphQL来获取数据的基本微服务应用程序。
GraphQL是Facebook发明和开源的一种API,可以更好地替代REST。可以将其理解为用于API的Querby语言,它可以通过公开单个端点并响应查询来进行声明式数据获取。在REST中,每种类型的请求总有一个专用端点,并且无法自定义。
在GraphQL中,客户端决定所需的数据,这就是客户端向服务器发送查询(有效负载),然后服务器根据查询请求将数据发送回的原因。他们在哪里获得名称GraphQL
优锐课带大家看一个例子来了解技术细节。在此示例中,我们将使用graphQL构建一个简单的书店应用程序。
pom.xml
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
}
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 URL:localhost:8080/bookstore/getAllBooks
和正文:query{ allBooks{bookId,bookName }}
你可以在主体部分中添加更多字段,因此,它将从服务器检索数据。
这就是本次演讲的全部内容。感受GraphQL的强大功能。