はじめに
CAPで作ったODataサービスをFiori elementsで使用する場合、ドラフトの有効化が必要です。しかし、ドラフト有効化したエンティティに対して(画面経由ではなく)HTTPリクエストで直接データを登録する場合、①ドラフト登録、②ドラフト有効化 という2ステップが必要になります。
本記事では、1回のリクエストでActiveなデータを登録する方法について説明します。
初期状態
@odata.draft.enabledアノテーションをつけたエンティティがあります。
using cap.bypass.draft from '../db/schema';
service OrdersService {
entity Orders as projection on draft.Orders;
}
annotate OrdersService.Orders with @odata.draft.enabled;
通常は、①ドラフト登録、②ドラフト有効化の2ステップが必要です。
### 1. Orders Draft POST
# @name Orders_Draft_POST
POST {{server}}/odata/v4/orders/Orders
Content-Type: application/json
Authorization: Basic {{username}}:{{password}}
{
"customerName": "customerName-4759079",
"orderDate": "2025-09-16",
"totalAmount": 100
}
### Result from POST request above
@draftID={{Orders_Draft_POST.response.body.$.ID}}
### 2. Orders Draft Activate
# @name Orders_Draft_Activate
POST {{server}}/odata/v4/orders/Orders(ID={{draftID}},IsActiveEntity=false)/OrdersService.draftActivate
Content-Type: application/json
Authorization: Basic {{username}}:{{password}}
{}
1ステップでActiveなデータを登録する方法
POSTリクエストのデータに"IsActiveEntity": trueという項目を含めます。
### POST Orders bypassing draft
POST {{server}}/odata/v4/orders/Orders
Content-Type: application/json
Authorization: Basic {{username}}:{{password}}
{
"customerName": "customerName-4759079",
"orderDate": "2025-09-16",
"totalAmount": 100,
"IsActiveEntity": true
}
ただし、これだけだと以下のエラーになってしまいます。
"
cds.env.fiori.bypass_draftmust be enabled or the entity must be annotated with@odata.draft.bypassto support direct modifications of active instances."
エラーメッセージの通り、回避方法は2つあります。
- エンティティレベルで
@odata.draft.bypassを許可
using cap.bypass.draft from '../db/schema';
service OrdersService {
entity Orders as projection on draft.Orders;
}
annotate OrdersService.Orders with @odata.draft.enabled;
annotate OrdersService.Orders with @odata.draft.bypass;
- package.jsonで
fiori.bypass_draft:trueを設定し、プロジェクト全体でドラフトのバイパスを許可
"cds": {
"fiori": {
"bypass_draft": true
}
}
おわりに
この方法は、Fiori elementsと他の(非UI系の)アプリケーションで同じODataサービスを利用したい場合に便利です。ただし、ドラフトを有効化した場合、GETリクエストの時もキーにIsActiveEntityを指定する必要があることに留意が必要です。
GET {{server}}/odata/v4/orders/Orders(ID={{draftID}},IsActiveEntity=true)