データ]

  • リンク:/tag/spring-data-rest/[春のデータREST]


1概要

この記事では、Spring Data RESTの予測と抜粋の概念について説明します。

投影法を使用してモデルのカスタムビューを作成する方法、および抜粋をリソースコレクションのデフォルトビューとして使用する方法を学習します。


2私たちのドメインモデル

まず、

Book



Author.

のドメインモデルを定義することから始めましょう。


Book

エンティティクラスを見てみましょう。

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @Column(nullable = false)
    private String title;

    private String isbn;

    @ManyToMany(mappedBy = "books", fetch = FetchType.EAGER)
    private List<Author> authors;
}

そして

Author

モデル:

@Entity
public class Author {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @Column(nullable = false)
    private String name;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
      name = "book__author",
      joinColumns = @JoinColumn(
        name = "book__id", referencedColumnName = "id"),
      inverseJoinColumns = @JoinColumn(
        name = "author__id", referencedColumnName = "id"))
    private List<Book> books;
}

この2つのエンティティは、多対多の関係もあります。

次に、モデルごとに標準のSpring Data RESTリポジトリを定義しましょう。

public interface BookRepository extends CrudRepository<Book, Long> {}

public interface AuthorRepository extends CrudRepository<Author, Long> {}

これで、

Book

エンドポイントにアクセスして、


http://localhost:8080/books/\

{id}のIDを使用して特定の

Book__詳細を取得できます

{
  "title" : "Animal Farm",
  "isbn" : "978-1943138425",
  "__links" : {
    "self" : {
      "href" : "http://localhost:8080/books/1"
    },
    "book" : {
      "href" : "http://localhost:8080/books/1"
    },
    "authors" : {
      "href" : "http://localhost:8080/books/1/authors"
    }
  }
}


Author

モデルはリポジトリを持っているので、作者の詳細はレスポンスの一部ではありません。しかし、それらへのリンクを見つけることができます –


http://localhost:8080/books/1/authors

.


3プロジェクションを作成する

場合によっては、エンティティの属性のサブセットまたはカスタムビューにのみ関心があります。そのような場合には、射影を利用できます。

Spring Data RESTプロジェクションを使用して、

Book

へのカスタムビューを作成しましょう。


CustomBook

という単純な

Projection

を作成することから始めます。

@Projection(
  name = "customBook",
  types = { Book.class })
public interface CustomBook {
    String getTitle();
}

  • 私たちの射影は

    @ Projection

    アノテーションを持つインターフェイスとして定義されていることに注意してください。

    name

    属性を使用して投影法の名前をカスタマイズしたり、

    types

    属性を適用してオブジェクトを定義したりできます。

この例では、

CustomBook

プロジェクションには本の__タイトルのみが含まれます。


Projectionを作成した後、

Book__表現をもう一度見てみましょう。

{
  "title" : "Animal Farm",
  "isbn" : "978-1943138425",
  "__links" : {
    "self" : {
      "href" : "http://localhost:8080/books/1"
    },
    "book" : {
      "href" : "http://localhost:8080/books/1{?projection}",
      "templated" : true
    },
    "authors" : {
      "href" : "http://localhost:8080/books/1/authors"
    }
  }
}

素晴らしいです、私たちは私たちの予測へのリンクを見ることができます。


http://localhost:8080/books/1で作成したビューを確認しましょう。projection

= customBook

:

{
  "title" : "Animal Farm",
  "__links" : {
    "self" : {
      "href" : "http://localhost:8080/books/1"
    },
    "book" : {
      "href" : "http://localhost:8080/books/1{?projection}",
      "templated" : true
    },
    "authors" : {
      "href" : "http://localhost:8080/books/1/authors"
    }
  }
}

ここでは、

title

フィールドのみが取得されていますが、

isbn

はカスタムビューには表示されていません。

原則として、


http://localhost:8080/books/1?projection

= \ {プロジェクション名} .

でプロジェクションの結果にアクセスできます。

また、私たちのモデルと同じパッケージで私たちの

射影

を定義する必要があることに注意してください。あるいは、

RepositoryRestConfigurerAdapter

を使用して明示的に追加することもできます。

@Configuration
public class RestConfig extends RepositoryRestConfigurerAdapter {

    @Override
    public void configureRepositoryRestConfiguration(
      RepositoryRestConfiguration repositoryRestConfiguration) {
        repositoryRestConfiguration.getProjectionConfiguration()
          .addProjection(CustomBook.class);
    }
}


4射影への新しいデータの追加

それでは、私たちの予測に新しいデータを追加する方法を見てみましょう。

前のセクションで説明したように、Projectionを使用してビューに含める属性を選択できます。さらに、元のビューに含まれていないデータを追加することもできます。


4.1. 隠しデータ

デフォルトでは、IDは元のリソースビューに含まれません。

結果のIDを確認するために、

id

フィールドを明示的に含めることができます。

@Projection(
  name = "customBook",
  types = { Book.class })
public interface CustomBook {
    @Value("#{target.id}")
    long getId();

    String getTitle();
}


__http://localhost:8080/books/1?projection = \ {プロジェクション名}

__の出力は次のようになります。

{
  "id" : 1,
  "title" : "Animal Farm",
  "__links" : {
     ...
  }
}


@JsonIgnore.

を使用して、元のビューから隠されていたデータも含めることができます。


4.2. 計算データ

リソース属性から計算された新しいデータを含めることもできます。

たとえば、著者の数をProjectionに含めることができます。

@Projection(name = "customBook", types = { Book.class })
public interface CustomBook {

    @Value("#{target.id}")
    long getId();

    String getTitle();

    @Value("#{target.getAuthors().size()}")
    int getAuthorCount();
}

そして、それを


http://localhost:8080/books/1?projection

= customBook

で確認できます。

{
  "id" : 1,
  "title" : "Animal Farm",
  "authorCount" : 1,
  "__links" : {
     ...
  }
}


4.3. 関連リソースへの簡単アクセス

最後に、この本の例のように、通常関連リソースにアクセスする必要がある場合は、それを明示的に含めることで余分な要求を回避できます。

@Projection(
  name = "customBook",
  types = { Book.class })
public interface CustomBook {

    @Value("#{target.id}")
    long getId();

    String getTitle();

    List<Author> getAuthors();

    @Value("#{target.getAuthors().size()}")
    int getAuthorCount();
}

そして最後の

Projection

出力は次のようになります。

{
  "id" : 1,
  "title" : "Animal Farm",
  "authors" :[{
    "name" : "George Orwell"
  }],
  "authorCount" : 1,
  "__links" : {
    "self" : {
      "href" : "http://localhost:8080/books/1"
    },
    "book" : {
      "href" : "http://localhost:8080/books/1{?projection}",
      "templated" : true
    },
    "authors" : {
      "href" : "http://localhost:8080/books/1/authors"
    }
  }
}

次に、抜粋を見てみましょう。


5抜粋

抜粋は、リソースコレクションのデフォルトビューとして適用される予測です。

コレクションのレスポンスに

customBook


Projection

を自動的に使用するように

BookRepository

をカスタマイズしましょう。

これを実現するために、

@ RepositoryRestResource

アノテーションの

excerptProjection

属性を使用します。

@RepositoryRestResource(excerptProjection = CustomBook.class)
public interface BookRepository extends CrudRepository<Book, Long> {}



http://localhost:8080/books


を呼び出して、

customBook

がbooksコレクションのデフォルトのビューであることを確認できます。

{
  "__embedded" : {
    "books" :[{
      "id" : 1,
      "title" : "Animal Farm",
      "authors" :[{
        "name" : "George Orwell"
      }],
      "authorCount" : 1,
      "__links" : {
        "self" : {
          "href" : "http://localhost:8080/books/1"
        },
        "book" : {
          "href" : "http://localhost:8080/books/1{?projection}",
          "templated" : true
        },
        "authors" : {
          "href" : "http://localhost:8080/books/1/authors"
        }
      }
    }]  },
  "__links" : {
    "self" : {
      "href" : "http://localhost:8080/books"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/books"
    }
  }
}



http://localhost:8080/authors/1/books


の特定の作者による書籍の表示にも同じことが当てはまります。

{
  "__embedded" : {
    "books" :[{
      "id" : 1,
      "authors" :[{
        "name" : "George Orwell"
      }],
      "authorCount" : 1,
      "title" : "Animal Farm",
      "__links" : {
        "self" : {
          "href" : "http://localhost:8080/books/1"
        },
        "book" : {
          "href" : "http://localhost:8080/books/1{?projection}",
          "templated" : true
        },
        "authors" : {
          "href" : "http://localhost:8080/books/1/authors"
        }
      }
    }]  },
  "__links" : {
    "self" : {
      "href" : "http://localhost:8080/authors/1/books"
    }
  }
}

前述のように、抜粋はコレクションリソースにのみ自動的に適用されます。

単一リソースの場合、前のセクションで示したように

projection

パラメーターを使用する必要があります。

これは、Projectionを単一リソースのデフォルトビューとして適用すると、部分的なビューからリソースを更新する方法を知るのが難しくなるためです。

最後の注意として、

予測と抜粋は読み取り専用

のためのものであることを覚えておくことが重要です。


6. 結論

Spring Data RESTプロジェクションを使用してモデルのカスタムビューを作成する方法を学びました。また、抜粋をリソースコレクションのデフォルトビューとして使用する方法も学びました。

例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-data-rest[over on GitHub]にあります。