ブログ

【SAP BTP】実装例で解説!Core Data Services(CDS)アノテーションの使い方

この記事をSNSでシェア!

SAP Business Technology Platform (BTP)環境でFioriアプリケーションを開発する際、多くの場合ODataを利用してデータ通信を行います。ODataの開発はSAP Cloud Application Programming Model(CAP)を使用することで、より簡単に行うことができます。
本記事では、データ検索に関連するCDSのアノテーションについて説明します。

CDSのアノテーションとは

Core Data Services(CDS)とはデータモデリング言語であり、データ定義やビジネスロジックを記述するために使用されます。
CAPでは、CDSのアノテーションを利用することでデータの表示方法や動作を制御することが可能です。画面側の変更が不要となるため、より効率的な開発が実現できます。

以下の実装例を通じて、データ検索に関するアノテーションの使い方を解説します。

  • BasicSearchの検索対象項目の設定
  • フィルター項目の必須制御
  • Value Help Dialogの実装

利用するアプリケーション

今回はBusiness Application Studio(BAS)のテンプレートを使用して、CAPプロジェクトとSAP Fioriアプリケーションを作成します。
初期設定されたFioriアプリケーションのUIが表示され、基本的な操作が可能です。
データモデルやサービス定義も既に用意されているため、これらを元に開発を進めることができます。

次に、定義とデータを修正します。
修正後のイメージ図は以下の通りです。

サービス定義
srv/cat-service.cds
using my.bookshop as my from '../db/data-model';
service CatalogService {
entity Books @readonly as projection on my.Books{
  ID,
  title,
  author.name as authorName,
  stock,
  category.categoryName,
  publisher
};
entity Authors @readonly as projection on my.Authors;
entity Category @readonly as projection on my.Category;
}
DB定義
db/data-model.cds
namespace my.bookshop;

entity Books {
  key ID     : Integer;
  title      : String @title : 'タイトル';
  authorID   : Integer;
  author     : Association to Authors on author.ID = $self.authorID;
  stock      : Integer @title : '在庫数';
  categoryID : Integer;
  category   : Association to Category on category.ID = $self.categoryID;
  publisher  : String @title : '出版社';
}
entity Authors {
    key ID : Integer;
    name   : String @title : '著者';
}

entity Category {
    key ID       : Integer;
    categoryName : String @title : 'カテゴリー名';
}
データ
db/data/my.bookshop-Books.csv
ID;name
1;著者1
2;著者2
3;著者3

以下の2つは新規で作成します。

db/data/my.bookshop-Authors.csv
ID;title;authorID;stock;categoryID;publisher
100;参考書;1;11;3;出版社A
101;旅行ガイド(北海道);2;22;2;出版社B
102;料理本;3;33;1;出版社C
103;辞書;1;44;3;出版社D
104;旅行ガイド(沖縄);2;55;2;出版社E
db/data/my.bookshop-Category.csv
ID;categoryName
1;カテゴリー1
2;カテゴリー2
3;カテゴリー3

BasicSearchの検索対象項目の設定

BasicSearchは画像の赤枠部分を指します。SmartFilterBarコンポーネントで利用可能な検索機能の一つで、複数のフィールドに対して、一括であいまい検索が可能です。
デフォルトでは、String型の項目が検索対象に設定されています。

実際に検索してみると、String型の「title」は検索できますが、Integer型の「ID」ではデータが見つからず、対象項目ではないことがわかります。

  • String型の項目「title」を検索
  • Integer型の項目「ID」を検索
実装方法

@cds.searchを使って、検索可能な項目を指定します。
trueもしくは項目名を記載している場合は検索対象項目に設定され、falseまたは項目名が記載されていない場合は検索対象外となります。
@Search.defaultSearchElementは非推奨になりました。(2024年6月現在)

実装例

例としてBooksEntityに対して@cds.searchを追加します。
設定内容は以下の通りです。

条件検索対象対象項目
デフォルト(String型のみ)title・publisher
①trueの記載なし(項目のみ)ID
②falseの記載あり×title
③仮想項目×author.name
④項目記載なし×publisher
data-model.cds
namespace my.bookshop;
@cds.search: {
              ID,                   //⓵
              title : false,        //⓶     
              author.name : true,   //⓷
              // publisher       ⓸
}
entity Books {
  key ID     : Integer;
  title      : String @title : 'タイトル';
  authorID   : Integer;
  author     : Association to Authors on author.ID = $self.authorID;
  stock      : Integer @title : '在庫数';
  categoryID : Integer;
  category   : Association to Category on category.ID = $self.categoryID;
  publisher  : String @title : '出版社';
  releaseDate  : Timestamp @title : '発売日';
}

  entity Authors {
    key ID : Integer;
    name   : String @title : '著者';
  }

  entity Category {
    key ID       : Integer;
    categoryName : String @title : 'カテゴリー名';
  }
実装結果

設定通りに、検索を制御できていることが確認できます。
①ID

②Title(タイトル)×

③author.name(著者)×

④publisher(出版社)×

フィルター項目の必須制御

次に、フィルター項目の必須制御について説明します。
フィルター項目は画像の赤枠部分にあるfilterBarの検索ボックスを指し、データのフィルタリングと検索を簡単に行うためのツールです。
フィルター項目を必須に設定することで、入力がない場合は検索を実行できないようにできます。

実装方法

フィルター項目を必須に設定するためには、ODataアノテーションの@Capabilitiesを使用します。
このアノテーションは、サービスの機能や動作を定義するために利用されます。

実装例

例として「ID」と「タイトル」を必須項目に設定します。
設定後のイメージ図は以下の通りです。

cat-service.cds
using my.bookshop as my from '../db/data-model';

service CatalogService {
  entity Books @readonly as projection on my.Books{
  ID,
  title,
  author.name as authorName,
  stock,
  category.categoryName,
  publisher
  };
  entity Authors @readonly as projection on my.Authors;
  entity Category @readonly as projection on my.Category;
}
annotate CatalogService.Books with @Capabilities : { 
  FilterRestrictions : {
      $Type : 'Capabilities.FilterRestrictionsType',
      RequiredProperties : [
        ID,
        title
      ]
  },
 };

RequiredProperties:必須項目に設定したい項目名を記載

実装結果

IDとタイトルに必須のマークがつき、
入力なしで検索を行うと、エラーメッセージが表示されます。

Value Help Dialogの実装方法

Value Help Dialogは、ユーザーが入力フィールドに値を入力する際に、選択肢を提供する機能です。
例えば、特定のフィールドに入力する値が決まっている場合、ユーザーはそのフィールドをクリックするだけで表示される選択肢リストから適切な値を選ぶことができます。

実装方法

Value Help Dialogの選択肢として使用するEntityに対して@cds.odata.valuelistを追加し、追加したEntityをValueListに追加します。

実装例

例として、「カテゴリーID」にValue Help Dialogを実装します。
実装後のイメージ図は以下の通りです。

1.選択肢として表示するEntity(Category)に対し、@cds.odata.valuelistを追加します。

data-model.cds
namespace my.bookshop;
@cds.search: {
              ID,                   //⓵
              title : false,        //⓶     
              author.name : true,   //⓷
              // publisher       ⓸
}
entity Books {
  key ID     : Integer;
  title      : String @title : 'タイトル';
  authorID   : Integer;
  author     : Association to Authors on author.ID = $self.authorID;
  stock      : Integer @title : '在庫数';
  categoryID : Integer;
  category   : Association to Category on category.ID = $self.categoryID;
  publisher  : String @title : '出版社';
}

  entity Authors {
    key ID : Integer;
    name   : String @title : '著者';
  }
  @cds.odata.valuelist
  entity Category {
    key ID       : Integer;
    categoryName : String @title : 'カテゴリー名';
  }

2.Value Help Dialogを実装するフィルター項目(categoryID)に対して、1で設定したEntityをValueListに追加します。

  • Common.ValueListWithFixedValues
     固定値のリストを使用するかどうかを指定(Boolean)
  • CollectionPath
     ValueListに追加するEntityやビューを指定(String)
  • SearchSupported
     ValueHelpDialog内の検索バーの表示有無を指定(Boolean)
  • $Type
    • ValueListParameterInOut
       入力と表示の両方で使用
    • ValueListParameterDisplayOnly
       表示のみで使用
  • LocalDataProperty
     検索対象のEntityの項目名を指定(String)
  • ValueListProperty
     @cds.odata.valuelistを設定したEntityのLocalDataPropertyに対応する項目名を指定(String)
cat-service.cds
using my.bookshop as my from '../db/data-model';

service CatalogService {
  entity Books @readonly as projection on my.Books{
  ID,
  title,
  author.name as authorName,
  stock,
  categoryID,
  category.categoryName,
  publisher
  };
  entity Authors @readonly as projection on my.Authors;
  entity Category @readonly as projection on my.Category;
}
 annotate CatalogService.Books with @Capabilities : { 
   FilterRestrictions : {
       $Type : 'Capabilities.FilterRestrictionsType',
       RequiredProperties : [
         ID,
         title
       ]
   },
  };
annotate CatalogService.Books with {
    categoryID     @(
        Common.ValueListWithFixedValues : false,
        Common.ValueList : {
            CollectionPath : 'Category',
            SearchSupported: true,
            Parameters     : [
                {
                    $Type            : 'Common.ValueListParameterInOut',
                    LocalDataProperty: 'categoryID',
                    ValueListProperty: 'ID',
                },
                {
                    $Type            : 'Common.ValueListParameterDisplayOnly',
                    ValueListProperty: 'categoryName',
                },
            ]
        }
    );
}
実装結果

「カテゴリーID」の検索ボックスを開くと、CategoryEntity内のデータが選択肢として表示されます。

検索もできていることが確認できます。

補足
Common.ValueListWithFixedValuesをtrueに設定した場合は、プルダウンメニューのような表示になります。

最後に

ここまでの説明は全てCDS Viewの変更のみで、画面側の修正は行っていません。
CDSアノテーションは、使い方を理解すれば簡単に制御でき、コードの削減にも役立ちました。
しかし、参考資料が少なく実装には時間がかかってしまいました。
そのため、必ずしも便利とは言い切れない部分もあります。
今後さらに学習を進めて、CDSアノテーションをより効果的に活用できるようになりたいと感じました。
本記事が少しでも参考になれば幸いです。

投稿者プロフィール

古家 碧
古家 碧
2023年に中途入社し、前職では主にJavaでの開発を担当していました。

現在は、SAP BTP・SAP Fioriを用いた開発案件に携わっています。
この記事をSNSでシェア!