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]にあります。