LinkRestへのガイド

1概要

LinkRest は、データ駆動型REST Webサービスを構築するためのオープンソースフレームワークです。これは JAX-RS Apache Cayenne ORM の上に構築されており、HTTP/JSONベースのメッセージプロトコルを使用します。

基本的に、このフレームワークはWeb上で私たちのデータストアを公開する簡単な方法を提供することを意図しています。

次のセクションでは、 LinkRest を使用してデータモデルにアクセスするためのREST Webサービスを構築する方法について説明します。

2 天国 依存関係

ライブラリを使い始めるには、まずhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22link-rest%22[ link-rest ]依存関係を追加する必要があります。

<dependency>
    <groupId>com.nhl.link.rest</groupId>
    <artifactId>link-rest</artifactId>
    <version>2.9</version>
</dependency>

これは cayenne-server アーティファクトももたらします。

さらに、 JAX-RS 実装として Jersey を使用するので、 jersey-container-servlet 依存関係、およびhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22jersey-media-moxy%22[ jersey-media-moxy ]JSONレスポンスをシリアル化するためのもの:

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.25.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>2.25.1</version>
</dependency>

この例では、セットアップが簡単であるため、インメモリ H2 データベースを使用します。その結果、https://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22h2%22%20AND%20g%3A%22com.h2database%22[ h2 ]も追加します。 :

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
</dependency>

3. Cayenne データモデル

これから扱うデータモデルには、 Department エンティティと一対多のリレーションシップを表す Employee エンティティが含まれています。

リンク:/uploads/tables.png%20526w[]

前述のように、 LinkRest Apache Cayenne ORM を使用して生成されたデータオブジェクトと連携します。 Cayenne を使った作業はこの記事の主な主題ではありません。詳細については、https://cayenne.apache.org/[ Apache Cayenne のドキュメント]を参照してください。

Cayenne プロジェクトを cayenne-linkrest-project.xml ファイルに保存します。

cayenne-maven-plugin を実行した後、これは2つの __Department および __Employee 抽象クラスを生成します。これらは CayenneDataObject クラス、およびそれらから派生した2つの具象クラス Department および Employee を拡張します。

これらの後者のクラスは、カスタマイズして LinkRest で使用できるクラスです。

4 LinkRest アプリケーション起動

次のセクションでは、RESTエンドポイントを作成してテストするので、それらを実行できるようにするには、ランタイムを設定する必要があります。

JAX-RS 実装として Jersey を使用しているので、 ResourceConfig を拡張し、RESTエンドポイントを定義するクラスを保持するパッケージを指定するクラスを追加しましょう。

@ApplicationPath("/linkrest")
public class LinkRestApplication extends ResourceConfig {

    public LinkRestApplication() {
        packages("com.baeldung.linkrest.apis");

       //load linkrest runtime
    }
}

同じコンストラクタで、 LinkRestRuntime を構築して Jersey コンテナに登録する必要があります。このクラスは最初の CayenneRuntime の読み込みに基づいています。

ServerRuntime cayenneRuntime = ServerRuntime.builder()
  .addConfig("cayenne-linkrest-project.xml")
  .build();
LinkRestRuntime lrRuntime = LinkRestBuilder.build(cayenneRuntime);
super.register(lrRuntime);

最後に、クラスを web.xml に追加する必要があります。

<servlet>
    <servlet-name>linkrest</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.baeldung.LinkRestApplication</param-value>
        </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>linkrest</servlet-name>
    <url-pattern>/** </url-pattern>
</servlet-mapping>

5 RESTリソース

モデルクラスが完成したので、RESTリソースを書き始めることができます。

  • RESTエンドポイントは標準の JAX-RS アノテーションを使用して作成され、レスポンスは LinkRest クラスを使用して構築されます。

この例では、さまざまなHTTPメソッドを使用して /department のURLにアクセスする一連のCRUDエンドポイントを作成します。

まず、 /department にマップされる DepartmentResource クラスを作成しましょう。

@Path("department")
@Produces(MediaType.APPLICATION__JSON)
public class DepartmentResource {

    @Context
    private Configuration config;

   //...
}

LinkRest クラスには、 JAX-RS によって提供される Context アノテーションを使用してインジェクトされる JAX-RS Configuration クラスのインスタンスが必要です。

次に、 Department オブジェクトにアクセスする各エンドポイントの作成を続けましょう。

5.1. POST を使用したエンティティの作成

エンティティを作成するために、 LinkRest クラスは UpdateBuilder オブジェクトを返す create() メソッドを提供します。

@POST
public SimpleResponse create(String data) {
    return LinkRest.create(Department.class, config).sync(data);
}

dataパラメーターは、 Department を表す単一のJSONオブジェクト、またはオブジェクトの配列のいずれかです。このパラメータは、 sync() メソッドを使用して UpdateBuilder に送信され、1つ以上のオブジェクトを作成してレコードをデータベースに挿入します。その後、メソッドは SimpleResponse を返します。

ライブラリはレスポンスのための3つの追加フォーマットを定義します。

  • DataResponse <T> - T のコレクションを表す応答

  • MetadataResponse <T> - 型に関するメタデータ情報を含みます

  • SimpleResponse - 2つの success message を含むオブジェクト

属性

次に、 curl を使用して Department レコードをデータベースに追加しましょう。

curl -i -X POST -H "Content-Type:application/json"
  -d "{"name":"IT"}" http://localhost:8080/linkrest/department

その結果、コマンドはステータス 201 Created success 属性を返します。

{"success":true}

JSON配列を送信して複数のオブジェクトを作成することもできます。

curl -i -X POST -H "Content-Type:application/json"
  -d "[{"name":"HR"},{"name":"Marketing"}]"
  http://localhost:8080/linkrest/department

5.2. GET を使用したエンティティの読み取り

オブジェクトを照会するための主なメソッドは、 LinkRest クラスの select() メソッドです。これは SelectBuilder オブジェクトを返します。これを使用して、追加のクエリまたはフィルタ処理メソッドをチェーニングできます。

データベース内のすべての Department オブジェクトを返す DepartmentResource クラスにエンドポイントを作成しましょう。

@GET
public DataResponse<Department> getAll(@Context UriInfo uriInfo) {
    return LinkRest.select(Department.class, config).uri(uriInfo).get();
}

uri() 呼び出しは SelectBuilder の要求情報を設定し、get()は DataResponse <Department> オブジェクトとしてラップされた Departments のコレクションを返します。

このエンドポイントを使用する前に追加した部門を見てみましょう。

curl -i -X GET http://localhost:8080/linkrest/department

応答は data 配列と total プロパティを持つJSONオブジェクトの形式を取ります。

{"data":[  {"id":200,"name":"IT"},
  {"id":201,"name":"Marketing"},
  {"id":202,"name":"HR"}],
"total":3}

あるいは、オブジェクトのコレクションを取得するために、 get() の代わりに getOne() を使用して単一のオブジェクトを取得することもできます。

与えられたIDを持つオブジェクトを返す /department/\ {departmentId} にマッピングされたエンドポイントを追加しましょう。そのために、 byId() メソッドを使用してレコードをフィルタ処理します。

@GET
@Path("{id}")
public DataResponse<Department> getOne(@PathParam("id") int id,
  @Context UriInfo uriInfo) {
    return LinkRest.select(Department.class, config)
      .byId(id).uri(uriInfo).getOne();
}

次に、このURLにGETリクエストを送信します。

curl -i -X GET http://localhost:8080/linkrest/department/200

結果は1つの要素を持つ data 配列です。

{"data":[{"id":200,"name":"IT"}],"total":1}

5.3. PUT を使用してエンティティを更新する

レコードを更新するには、 update() メソッドまたは createOrUpdate() メソッドを使用できます。後者は、存在する場合はレコードを更新し、存在しない場合は作成します。

@PUT
public SimpleResponse createOrUpdate(String data) {
    return LinkRest.createOrUpdate(Department.class, config).sync(data);
}

前のセクションと同様に、 data 引数は単一のオブジェクトまたはオブジェクトの配列です。

以前に追加した部門の1つを更新しましょう。

curl -i -X PUT -H "Content-Type:application/json"
  -d "{"id":202,"name":"Human Resources"}"
  http://localhost:8080/linkrest/department

これは成功またはエラーメッセージとともにJSONオブジェクトを返します。その後、ID 202の部署の名前が変更されたかどうかを確認できます。

curl -i -X GET http://localhost:8080/linkrest/department/202

もちろん、このコマンドは新しい名前のオブジェクトを返します。

{"data":[  {"id":202,"name":"Human Resources"}],
"total":1}

5.4. DELETE を使用したエンティティの削除

オブジェクトを削除するには、 DeleteBuilder を作成する delete() メソッドを呼び出してから、 id() メソッドを使用して削除するオブジェクトの主キーを指定します。

@DELETE
@Path("{id}")
public SimpleResponse delete(@PathParam("id") int id) {
    return LinkRest.delete(Department.class, config).id(id).delete();
}

その後、 curl を使用してこのエンドポイントを呼び出すことができます。

curl -i -X DELETE http://localhost:8080/linkrest/department/202

5.5. エンティティ間の関係を扱う

LinkRest には、オブジェクト間の関係の処理を容易にするメソッドも含まれています。

Department Employee と1対多の関係にあるので、 EmployeeSubResource クラスにアクセスする /department/\ {departmentId}/employees エンドポイントを追加します。

@Path("{id}/employees")
public EmployeeSubResource getEmployees(
  @PathParam("id") int id, @Context UriInfo uriInfo) {
    return new EmployeeSubResource(id);
}

EmployeeSubResource クラスは部署に対応しているため、部署IDと Configuration インスタンスを設定するコンストラクタがあります。

@Produces(MediaType.APPLICATION__JSON)
public class EmployeeSubResource {
    private Configuration config;

    private int departmentId;

    public EmployeeSubResource(int departmentId, Configuration configuration) {
        this.departmentId = departmentId;
        this.config = config;
    }

    public EmployeeSubResource() {
    }
}

オブジェクトをJSONオブジェクトとしてシリアル化するには、デフォルトのコンストラクタが必要であることに注意してください。

次に、部署からすべての従業員を取得するエンドポイントを定義しましょう。

@GET
public DataResponse<Employee> getAll(@Context UriInfo uriInfo) {
    return LinkRest.select(Employee.class, config)
      .toManyParent(Department.class, departmentId, Department.EMPLOYEES)
      .uri(uriInfo).get();
}

この例では、 SelectBuilder toManyParent() メソッドを使用して、特定の親を持つオブジェクトのみをクエリしました。

POST、PUT、DELETEメソッドのエンドポイントも同様に作成できます。

部署に従業員を追加するには、POSTメソッドを使用して departments/\ {departmentId}/employees エンドポイントを呼び出します。

curl -i -X POST -H "Content-Type:application/json"
  -d "{"name":"John"}" http://localhost:8080/linkrest/department/200/employees

次に、部門の従業員を表示するためにGETリクエストを送信しましょう。

curl -i -X GET "http://localhost:8080/linkrest/department/200/employees

これはデータ配列を持つJSONオブジェクトを返します。

{"data":[{"id":200,"name":"John"}],"total":1}

6. リクエストパラメータを使ったレスポンスのカスタマイズ

LinkRest は、リクエストに特定のパラメータを追加することによってレスポンスをカスタマイズする簡単な方法を提供します。これらを使用して、結果セットの一連の属性をフィルタリング、ソート、ページ付け、または制限することができます。

6.1. フィルタリング

cayenneExp パラメーターを使用して、属性の値に基づいて結果をフィルター処理できます。名前が示すように、これはhttp://cayenne.apache.org/docs/4.0/cayenne-guide/expressions.html[ Cayenne expressions]のフォーマットに従います。

「IT」という名前の部署のみを返すリクエストを送信しましょう。

curl -i -X GET http://localhost:8080/linkrest/department?cayenneExp=name='IT'

6.2. 並べ替え

結果のセットをソートするために追加するパラメータは sort dir です。

これらの最初のものはソートするための属性を指定し、2番目はソートの方向を指定します。

すべての部署を名前順に並べ替えてみましょう。

curl -i -X GET "http://localhost:8080/linkrest/department?sort=name&dir=ASC"

6.3. ページ付け

ライブラリは start limit パラメータを追加することでページネーションをサポートします。

curl -i -X GET "http://localhost:8080/linkrest/department?start=0&limit=2

6.4. 属性を選択する

include および exclude パラメーターを使用して、どの属性または関係が結果に返されるかを制御できます。

たとえば、部署の名前だけを表示するリクエストを送信しましょう。

curl -i -X GET "http://localhost:8080/linkrest/department?include=name

部署の名前だけでなく部署の従業員も表示するには、 include 属性を2回使用できます。

curl -i -X GET "http://localhost:8080/linkrest/department?include=name&include=employees.name

7. 結論

この記事では、 LinkRest フレームワークを使用して、RESTエンドポイントを介してデータモデルを素早く公開する方法を説明しました。

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