2
0

cds-pluginとは何か

Posted at

はじめに

この記事は SAP Advent Calendar 2023の 12月11日分の記事として執筆しています。

cds-pluginとは、CAPのアプリケーションに機能を追加することができる仕組みで、2023年3月にリリースされました。機能をパッケージ化しておき、他の複数のアプリケーションから利用することができます。

ここで「npmのライブラリとどう違うの?」という疑問が浮かぶかもしれません。プラグインは確かにnpmのライブラリとして提供されます。違いは、ライブラリは開発者が自分のソースの中で利用するのに対し、cds-pluginは使用先のアプリケーションのcdsファサード(API)に直接アクセスし、機能を実行する点です。このため使用先のアプリケーションで(ほとんど)コードを書くことなしに機能を追加することができます。
※機能を有効化するためにアノテーションをつけるなど、プラグインによって使い方は異なります

cds-pluginの仕組み

仕組み

cds-pluginを提供するパッケージは、package.jsonと同じ階層にcds-plugin.jsというファイルを置き、この中で処理を書きます。あとは、利用先のアプリケーションがプラグインをインストールするだけ、というとてもシンプルな仕組みです。

image.png

プラグインの作成

プラグインの仕組みを理解するために、以下のブログを参考に「特定のアノテーションをつけた項目に絵文字を追加する」プラグインを作成してみます。ソースコードは元のブログのものをそのまま使用している点をご承知おきください。

<ステップ>

  1. CAPプロジェクトを作成
  2. プラグインを作成
  3. CAPプロジェクトにプラグインを組み込み
  4. プラグインの実装
  5. CAPプロジェクトでアノテーションを追加

1. CAPプロジェクトを作成

以下のコマンドでCAPプロジェクトを作成し、サンプルのデータモデルを追加します。

cds init plugin-consumer 
cd plugin-consumer
cds add sample-tiny

2. プラグインを作成

plugin-consumerプロジェクトの中に新しくemojiPluginというフォルダを作成し、package.jsonファイルを追加します。

mkdir emojiPlugin && cd emojiPlugin && npm init -y && cd ..

image.png

cds-plugin.jsファイルを追加し、以下のコードを書きます。

console.log('my awesome plugin')

プロジェクトの構成は以下のようになります。
image.png

3. CAPプロジェクトにプラグインを組み込み

CAPプロジェクトのpackage.jsonに以下の設定を追加します。
※注意点:workspacesのほうはフォルダ名なので"P"が大文字、dependenciesのほうはプラグインのpackage.jsonのnameを指定するので"p"が小文字になります
image.png

npm installでdependencyをインストールし、cds watchでサービスを起動します。すると、コンソールにプラグインで出力したメッセージが表示されます。これによりプラグインが使用されていることが確認できます。
image.png

4. プラグインの実装

エンティティの項目に@randamEmojiというアノテーションがついている場合に、その項目の末尾にランダムな絵文字をつける実装をします。emojiPlugin/cds-plugin.jsを以下のように実装します。この例のように、cds-pluginでは使用先のアプリケーションのライフサイクルイベントやCRUDイベントなどに乗じて処理を挿入することが可能です。

const cds = require('@sap/cds')
// 絵文字の定義
const emojis = ["😀", "😃", "😄", "😁", "😆", "😅", "😂", "🤣", "🥲", "🥹", "😊", "😇", "🙂", "🙃", "😉", "😌", "😍"]
//our business logic...
function getRandomEmoji() {
  return emojis[Math.floor(Math.random() * emojis.length)]
}
// すべてのサービスがブートストラップされ、
// expressに追加されたタイミングで発生するイベントでロジックを追加する
cds.once('served', () => {
  // すべてのサービス、エンティティをトラバースして@randomEmojiアノテーションがついている項目を探す
  for (let srv of cds.services) {
    for (let entity of srv.entities) {
      const emojiElements = []
      for (const key in entity.elements) {
        const element = entity.elements[key]
        // 項目に@randomEmojiアノテーションがついているかをチェック
        if (element['@randomEmoji']) emojiElements.push(element.name)
      }
      // アノテーション付きの項目がある場合、READオペレーションの後に呼ばれるイベントハンドラを登録
      if (emojiElements.length) {
        srv.after('READ', entity, data => {
          if (!data) return
          // 単一レコードを取得した場合は配列にならないので、配列にする
          let myData = Array.isArray(data) ? data : [data]
          // アノテーションがついている項目を探して絵文字を追加
          for (let entry of myData) {
            for (const element of emojiElements) {
              if (entry[element]) {
                entry[element] += getRandomEmoji()
              }
            }
          }
        })
      }
    }
  }
})

5. CAPプロジェクトでアノテーションを追加

srv/cat-service.cdsファイルでアノテーションを追加します。

annotate CatalogService.Books with {
  title @randomEmoji;
};

ブラウザでエンティティを読み込むと、以下のように絵文字が付与されます。
image.png

この例では同一プロジェクトの中にプラグインのフォルダを作成しましたが、実際には独立したプロジェクトとして作成し、npmパッケージとして提供することが可能です。

提供されているプラグイン

12月7日現在、CAPireには以下のプラグインが掲載されています。

プラグイン パッケージ 説明
GraphQL Adapter @cap-js/graphql CAPのモデルに対してGraphQLのスキーマを生成し、GraphQLのクエリ言語でサービスを呼び出すためのエンドポイントを提供する。
OData v2 Proxy @cap-js-community/odata-v2-adapter OData V2のサービスを公開するためのプロトコルアダプター。以前は@sap/cds-odata-v2-adapter-proxyを使用していたが、プラグイン化することによってserver.jsを自分で実装しなくてよくなった。
UI5 Dev Server cds-plugin-ui5 UI5アプリをCDSサーバー上で動かすためのプラグイン。これを使うとCAPのプロジェクトの中で開発するUI5アプリでTypeScriptが使用可能になる。
Change Tracking @cap-js/change-tracking アノテーションをつけた項目について、変更履歴の保存と照会を可能にする。
Audit Logging @cap-js/audit-logging アノテーションをつけた(個人情報に関わる)項目で発生するイベントについて、Audit Log Serviceにログを残す。
Notifications @cap-js/notifications Alert Notificationsサービスへ通知を送信する(※)。

上記以外のプラグインは以下のページで確認できます。
https://bestofcapjs.org/#

※@cap-js/notificationsについて
CAPireのドキュメントでは上記の説明ですが、npmの説明ではSAP Build Work Zoneへ通知を送るという説明になっています。両方できるということなのでしょうか🤔
@cap-js/notificationsについて検証した記事はこちら

おわりに

プラグインは、複数のプロジェクトで共通的な処理を実装したいという場面でも使えそうです。たとえば、以下のようなプラグインが考えれます。

  • 共通的なフォーマットでログを出力するためのプラグイン
  • エラーハンドリングのためのプラグイン
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0