As the complexity of modern applications continues to increase, building scalable APIs and query systems has become increasingly important. In the past, REST API and SOAP were the mainstream API building solutions, but now GraphQL has also become a popular option. This article will introduce how to use Spring Boot and GraphQL to build an API and query system.
What is GraphQL?
GraphQL is a query language for APIs and query systems. Compared with traditional REST APIs, GraphQL has the following advantages:
Spring Boot and GraphQL
Spring Boot is a Java framework for building Java-based web applications. It provides many useful features such as automatic configuration and rapid development. Compared with traditional Java web development, Spring Boot can make the development process more enjoyable and efficient.
In this article, we will use Spring Boot and GraphQL to build a basic API and query system. Before you get started, you need to know the following components:
Building API and query system
First, we need to create a Spring Boot application. You can use Spring Initializr to quickly create a Spring Boot application. Here are the steps to create a Spring Boot application:
Creating a GraphQL Schema
Before creating a GraphQL Schema, let’s think about what our API needs to do. We will create an API with three types: author, book, and author-book relationship. The following are our API operations:
The next step is to create the GraphQL Schema. Schema defines the operations that can be performed on the API. In this article, we will use GraphQL Java Tools to create Schema. The steps to create GraphQL Schema are as follows:
type Author { id: ID! name: String! } type Book { id: ID! title: String! author: Author! } type Relationship { id: ID! author: Author! book: Book! } type Query { authors: [Author] author(id: ID!): Author books: [Book] book(id: ID!): Book relationships: [Relationship] booksByAuthor(authorId: ID!): [Book] }
This Schema defines three types: author, book and relationship. It also defines six operations: get author list, get author by ID, get book list, get books by ID, get relationship list and get associated books by author ID.
package com.example.demo; import com.example.demo.entity.*; import com.example.demo.repository.*; import com.example.demo.resolver.*; import java.util.List; import javax.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import graphql.schema.GraphQLSchema; import graphql.schema.idl.RuntimeWiring; import graphql.schema.idl.SchemaGenerator; import graphql.schema.idl.SchemaParser; import graphql.schema.idl.TypeRuntimeWiring; import graphql.servlet.GraphQLServlet; import graphql.servlet.SimpleGraphQLHttpServlet; @Configuration public class GraphQLProvider { private static final Logger LOGGER = LoggerFactory.getLogger(GraphQLProvider.class); private final AuthorRepository authorRepository; private final BookRepository bookRepository; private final RelationshipRepository relationshipRepository; private List<DataFetcher> fetchDataers; @Autowired public GraphQLProvider( AuthorRepository authorRepository, BookRepository bookRepository, RelationshipRepository relationshipRepository, List<DataFetcher> fetchDataers ) { this.authorRepository = authorRepository; this.bookRepository = bookRepository; this.relationshipRepository = relationshipRepository; this.fetchDataers = fetchDataers; } @PostConstruct public void setup() { fetchDataers.add(new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { return authorRepository.findAll(); } }); fetchDataers.add(new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { return authorRepository.findById(environment.getArgument("id")).get(); } }); fetchDataers.add(new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { return bookRepository.findAll(); } }); fetchDataers.add(new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { return bookRepository.findById(environment.getArgument("id")).get(); } }); fetchDataers.add(new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { return relationshipRepository.findAll(); } }); fetchDataers.add(new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { return bookRepository.findByAuthor_Id(environment.getArgument("authorId")); } }); } @Bean public GraphQLSchema schema() { SchemaParser schemaParser = new SchemaParser(); SchemaGenerator schemaGenerator = new SchemaGenerator(); TypeRuntimeWiring.Builder authorWiring = newTypeWiring("Author").dataFetchers(fetchDataers); return schemaGenerator.makeExecutableSchema(schemaParser.parse(getClass().getResource("/schema.graphqls").getPath()), RuntimeWiring.newRuntimeWiring() .type(authorWiring) .build()); } @Bean public GraphQLServlet graphQLServlet() { return new SimpleGraphQLHttpServlet(new GraphQL.Builder(schema()).build()); } }
This class creates a GraphQL service and adds the schema The .graphqls file is loaded into the service and Data Fetchers are defined. Data Fetchers are responsible for fetching data and populating it with the results of GraphQL operations.
Create JPA Entities and Repository
Now, we need to create the entities and map them into the database. In this article, we will create Author, Book and Relationship entities and map them to H2 database using JPA.
package com.example.demo.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.example.demo.entity.Author; @Repository public interface AuthorRepository extends JpaRepository<Author, Long> { }
package com.example.demo.entity; import lombok.Data; import javax.persistence.*; @Data @Entity public class Author { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; protected Author() {} public Author(String name) { this.name = name; } }
In the above example, we have created a Java entity named Author using the "id" and "name" fields of Lombok's @Data annotation.
Filling data
We can now populate the data using the H2 console or writing Java code.
Use H2 console to populate data:
INSERT INTO author (id, name) VALUES (1, 'William Shakespeare'); INSERT INTO author (id, name) VALUES (2, 'John Milton'); INSERT INTO author (id, name) VALUES (3, 'Charles Dickens'); INSERT INTO book (id, title, author_id) VALUES (1, 'Hamlet', 1); INSERT INTO book (id, title, author_id) VALUES (2, 'Paradise Lost', 2); INSERT INTO book (id, title, author_id) VALUES (3, 'Oliver Twist', 3); INSERT INTO relationship (id, author_id, book_id) VALUES (1, 1, 1); INSERT INTO relationship (id, author_id, book_id) VALUES (2, 2, 2); INSERT INTO relationship (id, author_id, book_id) VALUES (3, 3, 3);
使用Java代码填充数据:
package com.example.demo.seed; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import com.example.demo.entity.Author; import com.example.demo.entity.Book; import com.example.demo.entity.Relationship; import com.example.demo.repository.AuthorRepository; import com.example.demo.repository.BookRepository; import com.example.demo.repository.RelationshipRepository; @Component public class DataSeed implements CommandLineRunner { private AuthorRepository authorRepository; private BookRepository bookRepository; private RelationshipRepository relationshipRepository; public DataSeed(AuthorRepository authorRepository, BookRepository bookRepository, RelationshipRepository relationshipRepository) { this.authorRepository = authorRepository; this.bookRepository = bookRepository; this.relationshipRepository = relationshipRepository; } @Override public void run(String... args) throws Exception { Author shakespeare = new Author("William Shakespeare"); Author milton = new Author("John Milton"); Author dickens = new Author("Charles Dickens"); authorRepository.save(shakespeare); authorRepository.save(milton); authorRepository.save(dickens); Book hamlet = new Book("Hamlet", shakespeare); Book paradiseLost = new Book("Paradise Lost", milton); Book oliverTwist = new Book("Oliver Twist", dickens); bookRepository.save(hamlet); bookRepository.save(paradiseLost); bookRepository.save(oliverTwist); relationshipRepository.save(new Relationship(shakespeare, hamlet)); relationshipRepository.save(new Relationship(milton, paradiseLost)); relationshipRepository.save(new Relationship(dickens, oliverTwist)); } }
在上面的示例中,我们创建了一个CommandLineRunner工具类,它在应用程序启动时添加示例数据到数据库中。
测试GraphQL API
我们现在可以使用GraphQL Playground工具查询GraphQL API。
以下是一些示例查询:
获取作者列表:
query { authors { id name } }
按ID获取作者:
query { author(id: 1) { id name } }
获取书籍列表:
query { books { id title author { id name } } }
按ID获取书籍:
query { book(id: 1) { id title author { id name } } }
获取作者-书籍关系列表:
query { relationships { id author { id name } book { id title } } }
按作者ID获取关联书籍:
query { booksByAuthor(authorId: 1) { id title author { id name } } }
结论
本文介绍了如何使用Spring Boot和GraphQL构建API和查询系统,并执行基本的操作。可以使用GraphQL Java Tools和JPA轻松定义Schema和映射实体。GraphQL的灵活性和可扩展性使得它成为构建现代Web应用程序的理想选择。
The above is the detailed content of Build APIs and query systems using Spring Boot and GraphQL. For more information, please follow other related articles on the PHP Chinese website!