REST Builder
ご覧のページは、お客様の利便性のために一部機械翻訳されています。また、ドキュメントは頻繁に更新が加えられており、翻訳は未完成の部分が含まれることをご了承ください。最新情報は都度公開されておりますため、必ず英語版をご参照ください。翻訳に問題がある場合は、 こちら までご連絡ください。

REST Builderを使用したAPIの作成と実装

RESTビルダーを使用すると、構築したいAPIを定義でき、RESTビルダーはフレームワークとエンドポイントを提供します。

サンプルREST APIをデプロイする

RESTビルダーの動作を確認するために、カタログ内のIDによってダミー製品を取得するサンプルAPIをデプロイできます。 この簡単な例がどのように機能するかを理解したら、独自のアプリケーション用のAPIを作成できます。

新しいLiferay インスタンスを起動し、以下を実行します。

docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.132-ga132

http://localhost:8080 で Liferay にサインインしてください。 メールアドレス test@liferay.com とパスワード test を使用してください。 プロンプトが表示されたら、パスワードを learn に変更してください。

次に、以下の手順に従います。

  1. .zip アーカイブをダウンロードして解凍します。このアーカイブには Acme Foo API が含まれています。

    curl https://resources.learn.liferay.com/examples/liferay-r3b2.zip -O
    
    unzip liferay-r3b2.zip
    
  2. サンプルをビルドしてデプロイします。

    ./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
    
    注記

    このコマンドは、デプロイされたjarファイルをDockerコンテナの/opt/liferay/osgi/modulesにコピーするのと同じです。

  3. apiimpl バンドルの両方について、Dockerコンテナコンソールでデプロイを確認してください。

    com.acme.headless.r3b2.api_1.0.0 を開始しました
    com.acme.headless.r3b2.impl_1.0.0 を開始しました
    
  4. DXPインスタンスにログインし、 グローバルメニューGlobal Menu icon )→ コントロールパネルGogo Shellに移動します。

  5. Gogo Shellのプロンプトで、次のコマンドを入力します。

    jaxrs:チェック
    

    このページには、新しくデプロイされた API Liferay.Headless.R3B2 を含む、インストールされているすべての JAX-RS バンドルが一覧表示されます。 APIはデプロイされ、呼び出し可能な状態になりました。

    新しくデプロイされたAPI(Liferay.Headless.R3B2という名前)は、コマンドの結果として一覧表示され、すぐに使用できます。

  6. ターミナルから以下のコマンドを実行し、 {fooId} の部分を 1 から 3 の間の数値に置き換えて、API をテストしてください。

    curl -u 'test@liferay.com:learn' "http://localhost:8080/o/headless-r3b2/v1.0/foo/{fooId}"
    

    このクエリは、対応する製品のID、名前、説明をJSONオブジェクトにラップして返します。

    {
       "説明": "普遍的な真理は超越的でなければならない。"、
       "id": 1、
       "name": "Truth"
    }
    

おめでとうございます。新しいREST APIのデプロイと使用に成功しました。

REST Builderで生成されたAPIをご覧いただいたところで、次はそれがどのように動作するのかを理解しましょう。

初期設定

Liferayワークスペースプロジェクトに implapi モジュールを作成します。 impl モジュールの build.gradle ファイルは、REST Builder をプラグインとしてインストールおよび適用する必要があります。

buildscript {
   dependencies {
      classpath group: "com.liferay", name: "com.liferay.gradle.plugins.rest.builder", version: "1.1.32"
   }

   repositories {
      maven {
         url "https://repository-cdn.liferay.com/nexus/content/groups/public"
      }
   }
}

apply plugin: "com.liferay.portal.tools.rest.builder"

dependencies {
   compileOnly グループ: "com.liferay.portal"、名前: "release.dxp.api"
   compileOnly プロジェクト(":headless-r3b2-api")
}

両方のモジュールの build.gradle ファイルもポータル リリースへの依存関係を宣言する必要があります。

YAML設定

まず最初に行うべきことは、REST Builderの設定ファイルを作成することです。 impl モジュールのルートフォルダに、次の 2 つのファイルを追加します。 rest-config.yaml および rest-openapi.yaml。 これらのファイルには、REST BuilderがAPIの足場となるコードを生成するために必要なすべての情報が含まれている必要があります。

REST Builder構成を追加する

REST Builder の設定は rest-config.yaml ファイルにあります。 これは以下のフィールドを定義します。

apiDir: Javaソースコードフォルダ

apiPackagePath: REST Builder がすべてのモジュールにわたってコードを生成する開始 Java パッケージ パス

baseURI: このプロジェクト内のすべてのAPIのコンテキストURL

className: ルートリソースクラスのJavaクラス名(JAX-RSで使用)

javaEEPackage: コード生成に使用する名前空間。 この名前空間 は、API をデプロイする Liferay のバージョンと 一致する必要があります。 デフォルトでは、REST Builder は Java EE 名前空間 (javax ) を使用してコードを生成します。 Jakartaに移行した最新バージョンのLiferayを使用している場合は、Jakarta EE名前空間を使用するために、値を jakarta に設定してください。

名前: API の JAX-RS 名

以下の構造を使用して、これらのフィールドを定義します。

apiDir: "../headless-r3b2-api/src/main/java"
apiPackagePath: "com.acme.headless.r3b2"
application:
   baseURI: "/headless-r3b2"
   className: "HeadlessR3B2Application"
   名前: "Liferay.Headless.R3B2"
作者: "アミッタイの息子ヨナ"
クライアントディレクトリ: "../headless-r3b2-client/src/main/java"
testDir: "../headless-r3b2-test/src/testIntegration/java"

OpenAPI設定に情報ブロックを追加する

次に、 rest-openapi.yaml ファイルを開いて、API の設定を開始します。

最初に追加するセクションは情報ブロックです。

info:
   description:
      "Foo を返す API。"
   ライセンス:
      名前: "Apache 2.0"
      URL: "http://www.apache.org/licenses/LICENSE-2.0.html"
   タイトル: "Headless R3B2"
   バージョン: v1.0
openapi: 3.0.1
重要

ここで定義されている バージョン フィールドは、Liferay インスタンス内で API パスが公開されると URL の一部になります。

必要なスキーマを定義する

次に、 コンポーネント ブロックで、エンティティのスキーマを定義します。 REST Builderは、ここで定義した内容を使用して、これらのエンティティを表す対応するJava Beanを作成します。

表現したいエンティティごとに、 スキーマ ブロックを定義します。

コンポーネント:
   スキーマ:
      Foo:
         プロパティ:
               説明:
                  タイプ: 文字列
               ID:
                  フォーマット: int64
                  タイプ: 整数
               名前:
                  タイプ: 文字列
         タイプ: オブジェクト
      Goo:
         プロパティ:
               説明:
                  タイプ: 文字列
               fooId:
                  フォーマット: int64
                  タイプ: 整数
               id:
                  フォーマット: int64
                  タイプ: 整数
               名前:
                  タイプ: 文字列

この例では、 Foo というスキーマが、この API を使用する上で重要なデータを表しています。 Goo エンティティは、 fooId を使用して Foo にリンクされています。 スキーマでサポートされているデータ型の一覧については、 OpenAPI 仕様 を参照してください。

スキーマ定義によって、REST Builderが生成するクラス名(リソースファイル内のスキャフォールディングやテンプレートを含む)が決まります。 上記のスキーマは Foo および Barと呼ばれているため、実装ロジックは FooResourceImpl および GooResourceImpl クラスに属します。

APIを定義する

最後に、 パス ブロックを追加します。 これには、REST Builderで実装予定のすべてのAPIを含める必要があります。 以下は、パスブロックのごく一部です。


パス:
   "/foo":
      get:
      # get と post の操作はここに記述します。 完全なソースコードについては、プロジェクトを参照してください。
      # ...

   "/foo/{fooId}":
      get:
         operationId: getFoo
         # ...

         レスポンス:
               200:
                  コンテンツ:
                     application/json:
                           スキーマ:
                              $ref: "#/components/schemas/Foo"
                     application/xml:
                           スキーマ:
                              $ref: "#/components/schemas/Foo"
      # get、patch、put などの他の操作をここに配置します。 完全なソースコードについては、プロジェクトを参照してください。

   "/foo/{fooId}/goos":
      get:
         operationId: getFooGoosPage
         # これはFooとGoosの関係です。
         # ここにGETおよびPOST操作を記述してください。
         # ...

   "/goo/{gooId}":
      delete:
         operationId: deleteGoo

         # 必要に応じて他のエンティティに操作を配置します。
ヒント

getpostputpatch、および delete など、さまざまな種類のリクエストのパスを追加できます。

パス(foo/{fooId} )は、このAPI(getFoo)が、URLの末尾にこのパス文字列を追加することでアクセスできることを示しています(このURLには、rest-config.yamlファイルに指定された baseURIおよびversionの値も含まれます)。 例えば、この例の API には、完全な URL を介してアクセスします: localhost:8080/o/headless-r3b2/v1.0/foo/{fooId}

fooId に代入した値は、一致する名前のパラメータとして使用されます。

各パスには、パラメータブロックの下(かつgetブロック内)にresponsesブロックがあり、そこには少なくとも成功した呼び出し(200レスポンスで示される)に対するレスポンスが定義されています。

この レスポンス ブロックは、呼び出しが成功すると Product が返されることを指定します。 文字列 #/components/schemas/Foo は、同じファイルで以前に定義されたスキーマを参照し、REST Builder が Foo スキーマをこの API の戻り値の型として使用できるようにします。

最後に、 タグ 定義を、 レスポンス ブロックの下に追加します。

タグ: ["Foo"]

このタグは、REST Builderがスキャフォールディングコードに注釈を付ける際に、生成されるドキュメントに追加される情報を指定します。 タグ名は、スキーマ名と一致させる必要があります。

完全なリファレンスについては、以前ダウンロードした rest-openapi.yaml ファイルを参照してください。

また、関係性をどのように表現できるかを示すために、 Goo オブジェクトもあります。Goo は fooId に関連付けられているという意味で Foo と関連しています。

REST Builderを実行する

REST Builder がほとんどの作業を実行するために必要なすべての構成を追加したので、 impl モジュール内から次のコマンドを実行して、 buildREST Gradle タスクを実行します。

../gradlew buildREST

REST Builder は、設定を使用して、 apiimpl クラスの両方にスキャフォールディング コードと、実装ロジックを追加できる Java クラスを生成します。

GraphQLエンドポイントコードとJAX-RSアプリケーションコードは、それぞれ graphqljaxrs パッケージで生成されます。 独自の API 実装は、 リソース パッケージ内の適切な *ResourceImpl クラスに追加されます。

実装ロジックを追加

最後のステップは、定義した各APIのロジックを定義することです。 impl モジュール内で、 rest-openapi.yaml で定義したスキーマ名に基づいて、実装が配置される Java リソース クラスを見つけます (この例では、 FooResourceImpl.javaGooResourceImpl.java)。

ヒント

実装用のクラスの場所は、 rest-config.yaml ファイルで apiPackagePath に定義した値によって決まります。 そのパスをたどり、その中の internal/resource/<version>/ に移動します。 この例と同じパスを使用した場合、ファイルは src/main/java/com/acme/headless/r3b2/internal/resource/v1_0/ 内にあります。

実装クラス ([SchemaName]ResourceImpl) は、基底クラス (Base[SchemaName]ResourceImpl ) の隣にあります。 実装クラスを開きます。 これは単なる例なので、この実装では事前にデータが入力された HashTableを使用し、 getFoo メソッドは、一致する fooId を持つ HashTable からの積を返します。 完全な実装については、プロジェクト内の FooResourceImpl.java を参照してください。

	@Override
	public Foo getFoo(Integer fooId) {
		return _foos.get(fooId);
}

このメソッドは、特別な JAX-RS アノテーションを使用して定義されている基底クラス (Base[SchemaName]ResourceImplで定義されている基底メソッドをオーバーライドします。

リクエストを完了するために、任意のビジネスロジックを追加できます。 REST Builderは、スキーマで定義したオブジェクトのデフォルトコンストラクターのみを作成します。 このビジネスロジックの例では、オブジェクトを作成し、そのオブジェクトに値を追加します(rest-openapi.yaml でのパラメータの定義に基づいて)。

   Foo foo1 = new Foo() {
      {
         description = "普遍的な真理は超越的でなければならない。";
         id = 1L;
         name = "真理";
      }
};

Goo のロジックは似ていますが、この場合は Foo オブジェクトが複数の Gooを含むことができるため、複数の Gooが返されます。 オブジェクトのコレクションを返す場合は、ページネーションに対応したオブジェクトである Page を使用する必要があります。

	@Override
	public Page<Goo> getFooGoosPage(Long fooId) {
		List<Goo> goos = new ArrayList<>();

		for (Goo goo : _goos.values()) {
			if (Objects.equals(fooId, goo.getFooId())) {
				goos.add(goo);
			}
		}

		return Page.of(goos);
}

GraphQL名前空間を追加する

Liferayは、GraphQLアプリケーション向けの名前空間設定をサポートしています。 名前空間を使用すると、特定のアプリケーションにおけるクエリ、ミューテーション、および型をグループ化できます。 名前空間を指定することで、異なるアプリケーションで同じスキーマを重複して使用することも可能です。

情報

Liferay アプリケーションで GraphQL を使用する方法の詳細については、 GraphQL API の利用 を参照してください。

GraphQL名前空間を追加して使用するには、以下の手順に従ってください。

  1. アプリケーションのimplモジュールでrest-config.yamlファイルを開く。

  2. graphQLNamespace フィールドに、目的の名前空間名を追加します。

    graphQL名前空間: "<namespace name>"
    
  3. 目的のクエリまたはミューテーションオブジェクトの1つ下の階層に名前空間を追加します。

    クエリ{
       <namespace name> {
    ...
       }
    }
    
  4. REST Builderを実行して、指定されたすべてのクエリとミューテーションをネームスペースに公開します。

GraphQL拡張機能内の名前空間には、 GraphQLContributor インターフェースを使用してアクセスすることもできます。 getGraphQLNamespace メソッドを実装して、目的の名前空間名を返します。

public class MyGraphQLContributor implements GraphQLContributor {
...

   @Override
   public String getGraphQLNamespace() {
      return "<namespace name>";
   }

...
}

GraphQL拡張機能では、名前空間はデフォルトで無効になっています。

結論

おめでとう! これで、REST Builder を使用した新しい API の実装の基本を理解し、DXP に新しい API を追加することができました。