隨著現代應用程式的複雜性不斷提高,建立可擴展的API和查詢系統變得越來越重要。在過去,REST API和SOAP都是主流的API建置方案,但現在GraphQL也成為了受歡迎的選項。本文將介紹如何使用Spring Boot和GraphQL建構API和查詢系統。
什麼是GraphQL?
GraphQL是一種用於API和查詢系統的查詢語言。與傳統的REST API相比,GraphQL有以下優勢:
Spring Boot和GraphQL
Spring Boot是一個Java框架,用於建立基於Java的網路應用程式。它提供了許多有用的功能,例如自動配置和快速開發。與傳統的Java Web開發相比,Spring Boot可以使開發過程變得更加愉快和有效率。
在本文中,我們將使用Spring Boot和GraphQL來建立一個基本的API和查詢系統。在開始之前,您需要了解以下幾個元件:
建立API和查詢系統
首先,我們需要建立一個Spring Boot應用程式。您可以使用Spring Initializr來快速建立一個Spring Boot應用程式。以下是創建一個Spring Boot應用程式的步驟:
建立GraphQL Schema
在建立GraphQL Schema之前,讓我們先考慮一下我們的API需要執行哪些動作。我們將創建一個具有三種類型的API:作者,書籍和作者-書籍關係。以下是我們的API運算:
下一步是建立GraphQL Schema。 Schema定義了可以在API上執行的操作。在本文中,我們將使用GraphQL Java Tools來建立Schema。建立GraphQL Schema的步驟如下:
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] }
這個Schema定義了三個類型:作者,書籍和關係。它還定義了六個操作:獲取作者列表,按ID獲取作者,獲取書籍列表,按ID獲取書籍,獲取關係列表和按作者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()); } }
該類別建立一個GraphQL服務,將schema .graphqls檔案載入到該服務中,並定義了Data Fetchers。 Data Fetchers負責取得資料並填入GraphQL操作的結果。
建立JPA實體和儲存庫
現在,我們需要建立實體並將它們對應到資料庫中。在本文中,我們將建立Author,Book和Relationship實體,並使用JPA將其對應到H2資料庫。
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; } }
在上面的範例中,我們使用Lombok的@Data註解的「id」和「name」欄位建立了一個名為Author的Java實體。
填入資料
我們現在可以使用H2控制台或寫一個Java程式碼來填入資料。
使用H2控制台填入資料:
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应用程序的理想选择。
以上是使用Spring Boot和GraphQL建構API和查詢系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!