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

RESTビルダーを使用した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. apiバンドルとimplバンドルの両方のDockerコンテナコンソールでのデプロイを確認します。

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

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

    jaxrs:check
    

    このページには、新しくデプロイされた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}"
    

    クエリは、JSONオブジェクトでラップされた対応する製品のID、名前、および説明を返します。

    {
       "description": "Universal truth must be transcendental.",
       "id": 1,
       "name": "Truth"
    }
    

新しいREST APIを正常にデプロイして使用しました。

RESTビルダーで生成されたAPIを確認したので、次はそれがどのように機能するかを理解します。

初期設定

Liferay Workspaceプロジェクトでimplおよびapiモジュールを作成することから始めます。 implモジュールのbuild.gradleファイルは、RESTビルダーをプラグインとしてインストールして適用する必要があります。

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 group: "com.liferay.portal", name: "release.portal.api"
   compileOnly project(":headless-r3b2-api")
}

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

YAML構成

最初のステップは、RESTビルダー構成ファイルを作成することです。 implモジュールのルートフォルダに、rest-config.yamlrest-openapi.yamlの2つのファイルを追加します。 これらのファイルには、RESTビルダーがAPIのビルディングブロックコードを生成するために必要なすべての情報が含まれている必要があります。

RESTビルダー構成を追加する

RESTビルダーの構成はrest-config.yamlファイルに属します。 この構成では次のフィールドを定義します。

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

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

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

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

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

name:APIのJAX-RS名

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

apiDir: "../headless-r3b2-api/src/main/java"
apiPackagePath: "com.acme.headless.r3b2"
application:
   baseURI: "/headless-r3b2"
   className: "HeadlessR3B2Application"
   name: "Liferay.Headless.R3B2"
author: "Jonah the son of Amittai"
clientDir: "../headless-r3b2-client/src/main/java"
testDir: "../headless-r3b2-test/src/testIntegration/java"

OpenAPI構成に情報ブロックを追加する

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

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

info:
   description:
      "API to return a Foo."
   license:
      name: "Apache 2.0"
      url: "http://www.apache.org/licenses/LICENSE-2.0.html"
   title: "Headless R3B2"
   version: v1.0
openapi: 3.0.1
重要

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

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

次に、componentsブロックで、エンティティのスキーマを定義します。 RESTビルダーは、ここで定義したものを使用して、これらのエンティティを表す対応するJavaBeansを作成します。

表現するエンティティごとにschemaブロックを定義します。

components:
   schemas:
      Foo:
         properties:
               description:
                  type: string
               id:
                  format: int64
                  type: integer
               name:
                  type: string
         type: object
      Goo:
         properties:
               description:
                  type: string
               fooId:
                  format: int64
                  type: integer
               id:
                  format: int64
                  type: integer
               name:
                  type: string

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

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

APIを定義する

最後に、pathsブロックを追加します。 これには、RESTビルダーで実装する予定のすべてのAPIが含まれている必要があります。 パスブロックの小さなスニペットを次に示します。


paths:
   "/foo":
      get:
      # operations for get and post go here. See the project for full source code.
      # ...

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

         responses:
               200:
                  content:
                     application/json:
                           schema:
                              $ref: "#/components/schemas/Foo"
                     application/xml:
                           schema:
                              $ref: "#/components/schemas/Foo"
      # Place other operations, such as get, patch, and put here. See the project for full source code.

   "/foo/{fooId}/goos":
      get:
         operationId: getFooGoosPage
         # This is the relationship between Foos and Goos.
         # Place your get and post operations here.
         # ...

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

         # Place operations on other entities as needed.
ヒント

getpostputpatchdeleteなど、さまざまな種類のリクエストのパスを追加できます。

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

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

各パスには、parametersブロックの下(およびgetブロック内)にresponsesブロックがあり、少なくとも成功した呼び出しの応答(200応答で示される)を定義します。

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

最後に、responsesブロックの下に、このパスのtags定義を追加します。

tags: ["Foo"]

このタグは、RESTビルダーがビルディングブロックコードにアノテーションを付けるときに生成されたドキュメンテーションに追加される情報を指定します。 タグ名は、スキーマの名前を反映している必要があります。

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

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

RESTビルダーを実行する

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

../gradlew buildREST

RESTビルダーはこの構成を使用して、apiクラスとimplクラスの両方にビルディングブロックコードと、実装ロジックを追加できるJavaクラスを取り込みます。

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

実装ロジックを追加する

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

ヒント

実装のクラスの場所は、 apiPackagePathrest-config.yaml ファイルで定義した値によって異なります。 そのパスに従って、その中の 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ビルダーは、スキーマで定義したオブジェクトのデフォルトコンストラクターのみを作成します。 このサンプルのビジネスロジックは、オブジェクトを作成し、それに値を追加します(rest-openapi.yamlparametersを定義した方法に基づく)。

   Foo foo1 = new Foo() {
      {
         description = "Universal truth must be transcendental.";
         id = 1L;
         name = "Truth";
      }
   };

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 フィールドを追加します。

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

    query{
       <namespace name> {
          ...
       }
    }
    
  4. REST ビルダーを実行して、名前空間内のすべての指定されたクエリとミューテーションを公開します。

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

public class MyGraphQLContributor implements GraphQLContributor {
   ...

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

   ...
}

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

さいごに

これで、 これで、RESTビルダーを使用して新しいAPIを実装するための基本を理解し、DXPに新しいAPIを追加しました。