首頁 > Java > java教程 > 使用Spring Boot和GraphQL建構API和查詢系統

使用Spring Boot和GraphQL建構API和查詢系統

WBOY
發布: 2023-06-22 11:31:22
原創
1451 人瀏覽過

隨著現代應用程式的複雜性不斷提高,建立可擴展的API和查詢系統變得越來越重要。在過去,REST API和SOAP都是主流的API建置方案,但現在GraphQL也成為了受歡迎的選項。本文將介紹如何使用Spring Boot和GraphQL建構API和查詢系統。

什麼是GraphQL?

GraphQL是一種用於API和查詢系統的查詢語言。與傳統的REST API相比,GraphQL有以下優勢:

  • 靈活性:GraphQL允許客戶端指定所需的數據,因此可以避免不必要的資料傳輸。
  • 可擴充性:GraphQL為客戶端和伺服器提供了高度的靈活性,因此可以輕鬆地新增新的欄位或操作。
  • 效能:由於GraphQL允許客戶端指定所需的數據,因此可以避免過度拉取資料。

Spring Boot和GraphQL

Spring Boot是一個Java框架,用於建立基於Java的網路應用程式。它提供了許多有用的功能,例如自動配置和快速開發。與傳統的Java Web開發相比,Spring Boot可以使開發過程變得更加愉快和有效率。

在本文中,我們將使用Spring Boot和GraphQL來建立一個基本的API和查詢系統。在開始之前,您需要了解以下幾個元件:

  • Spring Boot:用於建立基於Java的網路應用程式。
  • GraphQL Java:Java的GraphQL實作。
  • Spring Boot Starter Data JPA:用於將Spring Boot和Java Persistence API(JPA)整合在一起。
  • H2資料庫:用於本地開發和測試的記憶體資料庫。

建立API和查詢系統

首先,我們需要建立一個Spring Boot應用程式。您可以使用Spring Initializr來快速建立一個Spring Boot應用程式。以下是創建一個Spring Boot應用程式的步驟:

  • 打開Spring Initializr網站。
  • 選擇您的Spring Boot版本。
  • 可以選擇您喜歡的建置工具,例如Maven或Gradle。
  • 新增所需的依賴項。在本文中,我們需要“Spring Web”,“GraphQL Java Tools”,“GraphQL Java Spring Boot Starter”,“Spring Boot Starter Data JPA”和“H2 Database”。
  • 點擊「生成」按鈕,將下載基本的Spring Boot應用程式結構。

建立GraphQL Schema

在建立GraphQL Schema之前,讓我們先考慮一下我們的API需要執行哪些動作。我們將創建一個具有三種類型的API:作者,書籍和作者-書籍關係。以下是我們的API運算:

  • 取得作者清單:傳回作者清單。
  • 按ID取得作者:按作者ID返回作者詳細資料。
  • 取得書籍清單:返回書籍清單。
  • 按ID取得書籍:按書籍ID返回書籍詳細資料。
  • 取得作者-書籍關係清單:返回作者-書籍關係清單。
  • 按作者ID取得關聯書籍:按作者ID返回該作者的所有書籍詳細資料。

下一步是建立GraphQL Schema。 Schema定義了可以在API上執行的操作。在本文中,我們將使用GraphQL Java Tools來建立Schema。建立GraphQL Schema的步驟如下:

  • 在src/main/resources資料夾中建立一個名為「schema.graphqls」文件,並新增以下程式碼:
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獲取關聯書籍。

  • 在專案中建立GraphQL服務並將schema.graphqls檔案載入到該服務中。在src/main/java/com.example.demo資料夾中建立一個名為「GraphQLProvider」的新類,其中包含以下程式碼:
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資料庫。

  • 在src/main/java/com.example.demo.repository 套件中建立名為「AuthorRepository」的新接口,其中包含以下程式碼:
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> {
}
登入後複製
  • 依照上述方法,建立BookRepository和RelationshipRepository。
  • 在src/main/java/com.example.demo.entity套件中建立實體和關係。以下是作者實體的範例程式碼:
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控制台填入資料:

  • 在src/main/resources文件夹中创建一个名为“data.sql”的文件,并添加以下代码:
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);
登入後複製
  • 启动应用程序并访问http://localhost:8080/h2-console。
  • 在H2控制台中,更改JDBC URL为jdbc:h2:mem:testdb并单击Connect按钮。
  • 执行data.sql文件中的查询以填充数据。

使用Java代码填充数据:

  • 在src/main/java/com.example.demo.seed包中创建一个新类并命名为“DataSeed”,其中包含以下代码:
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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板