ホームページ  >  記事  >  Java  >  Spring Boot と GraphQL を使用して API とクエリ システムを構築する

Spring Boot と GraphQL を使用して API とクエリ システムを構築する

WBOY
WBOYオリジナル
2023-06-22 11:31:221427ブラウズ

最新のアプリケーションの複雑さが増すにつれ、スケーラブルな 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 ベースの Web アプリケーションを構築するための Java フレームワークです。自動構成や迅速な開発など、多くの便利な機能を提供します。従来の Java Web 開発と比較して、Spring Boot は開発プロセスをより楽しく効率的に行うことができます。

この記事では、Spring Boot と GraphQL を使用して、基本的な API とクエリ システムを構築します。始める前に、次のコンポーネントについて理解しておく必要があります。

  • Spring Boot: Java ベースの Web アプリケーションの構築に使用されます。
  • 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 Web サイトを開きます。
  • Spring Boot バージョンを選択します。
  • Maven や Gradle など、好みのビルド ツールを選択できます。
  • 必要な依存関係を追加します。この記事では、「Spring Web」、「GraphQL Java Tools」、「GraphQL Java Spring Boot Starter」、「Spring Boot Starter Data JPA」、「H2 Database」が必要です。
  • [生成] ボタンをクリックすると、基本的な Spring Boot アプリケーション構造がダウンロードされます。

GraphQL スキーマの作成

GraphQL スキーマを作成する前に、API が何を行う必要があるかを考えてみましょう。著者、書籍、著者と書籍の関係の 3 つのタイプを持つ API を作成します。 API オペレーションは次のとおりです。

  • 著者リストの取得: 著者リストを返します。
  • 著者を ID で取得: 著者 ID で著者の詳細を返します。
  • 書籍リストの取得:書籍リストを返します。
  • ID で書籍を取得: 書籍 ID で書籍の詳細を返します。
  • 著者と本の関係リストを取得する: 著者と本の関係リストを返します。
  • 著者 ID によって関連する書籍を取得: 著者 ID によって著者のすべての書籍の詳細を返します。

次のステップは、GraphQL スキーマを作成することです。スキーマは、API で実行できる操作を定義します。この記事では、GraphQL Java ツールを使用してスキーマを作成します。 GraphQL スキーマを作成する手順は次のとおりです。

  • 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]
}

このスキーマは、著者、書籍、関係の 3 つのタイプを定義します。また、著者リストの取得、ID による著者の取得、書籍リストの取得、ID による書籍の取得、関係リストの取得、著者 ID による関連書籍の取得の 6 つの操作も定義されています。

  • プロジェクト内に 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 サービスを作成し、スキーマを追加します。 .graphqls ファイルがサービスにロードされ、データ フェッチャーが定義されます。データ フェッチャーは、データをフェッチし、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 パッケージにエンティティと関係を作成します。以下は、Author エンティティのサンプル コードです。
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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。