この記事は chillSAP 夏の自由研究2022、8/7の記事として執筆しています。
はじめに
この記事では、ODataにあまり馴染みにないSAPコンサルタント向け(私もその一人です)向けに
- ODataの基本
- ODataの探し方
- ODataの基本的な操作方法
について解説します。
ODataってなんぞや
一言でいうとWebAPIの一種です。
詳しい定義については、↑のリンク等を参照していただきたいです。
このODataという仕組み、何がすごいかってCRUD全部に対応していることです。
私は以前通常のWebAPIの設計をやったことがあるのですが、実装するのはCRUDのうちどれか一つなんです。
それがODataだとSelectもInsertもUpdateもDeleteも全部できちゃいます。
すごいですよね。
またODataはEntityというデータモデルから構成されていて、これがテーブルを操作するような感覚で使えてしまいます。
何度かODataを触って思いましたが、SAPの標準ないしアドオンのオブジェクト(テーブル)を、構造に値を代入しながら参照・更新できるという意味において、従来のABAPerにとっては標準のBAPIとか汎用モジュールみたいなもんだなと思いました。
SAP API HUBからODataを探してみる
S/4HANAにかぎらず、あらゆるSAP製品のAPIは下記のページから参照可能です。
今回はオンプレ版のS/4HANAのODataを参照してみましょう。
トップページから、
Products > S/4HANA > APIsと進みます。
SAPのAPIには、ODataの他にSOAPという形式もあるみたいなのですが、よくわからないのでここでは割愛します。
さて、2022年8月現在、SAPがサポートしているODataにはV2とV4の二種類があります。
例えば銀行マスタ(BANK)をメンテするODataを検索してみましょう。
V2とV4の両方で見つかります。
V2とV4で何が違うかよくわかりませんが、今回はBANK ODATA V4 API Version2.0.0の各タブを覗いてみましょう。
API Reference
このタブでは各種CRUD処理におけるAPIの呼び出し例が記述されています。
概ね、
参照:GET
登録:POST
更新:PATCH
だと思っていただければ問題ないと思います。
Schema View
ここでは、各パラメータの意味や型、必須/任意などを確認できます。
SAPに慣れている人ならわかると思いますが、ほぼほぼ実テーブルの項目定義と適合しています。
見ての通りほぼ項目レベルで対応しているのがわかると思います。
SAPシステムからODataサービスを確認する方法
SAPにどんなODataがあるのか、GUIからTCodeを使って確認できます。
前述の通りSAPのODataにはV2とV4がありますが、それぞれ確認できる口が異なります。
V2の場合
TCODE:/n/IWBEP/REG_SERVICE で検索すると以下の通りHitします。
V4の場合
TCode:/n/IWFND/V4_ADMIN
ODataサービスをSAP内部から動作確認する
上記で探したODataをGUIの内部から実際に使ってみることができます。
前述のV4のODataを触ってみましょう。
Service Testを押下します。
すると、SAP Gateway clientという画面が立ち上がります。
TCode:/n/IWFND/GW_CLIENT からでもアクセス可能です。
試しに、API HUBにかかれている取得の仕方を試してみます。
HTTPメソッドはGETにし、↓のRequestURIを入力してExecuteします。
/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_bank_2/0001/Bank?$top=10
今度は、POSTメソッドで登録をやってみましょう
↓RequestURI
/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_bank_2/0001/Bank
↓リクエストBody
{
"BankCountry": "JP",
"BankInternalID": "0006004",
"BankName": "TESTBANK",
"Region": "27"
}
HTTPメソッドをPOSTにしてExecuteします。
Statusが201で返ってきているので成功ですね。
(HTTPリクエストのHeaderに、つけてもないのにX-CSRF-Tokenがひっついてきていますが、こちらについてはあとで解説します。)
ODataサービスをSAP外部から動作確認する
ODataはインターネットに公開されたWebAPIなので、GUIでなくてもHTTPクライアントのソフトからも叩くことができます。
今回私はVSCodeのExtensionであるREST Clientで動作確認してみました。
(POSTMANとかでもいけると思います。)
今回はSAP外部からアクセスするので、/sapより右だけでなくRootURLを付与する必要があります。
内部からやったときと同じ要領でGETしてみましょう。
https:[RootURL]/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_bank_2/0001/Bank?$top=10
HTTP/1.1 401 Unauthorized
content-type: text/html; charset=utf-8
content-length: 6613
sap-system: XXX
www-authenticate: Basic realm="SAP NetWeaver Application Server [XXX/100]"
sap-server: true
このように401が返ってきます。
内部から動作確認した時は何も付与する必要がなかったのですが、外部からアクセスするときはBASIC認証をしてあげる必要があります。
SAPのIDPWをリクエストに含める必要があるってことですね。
https:[RootURL]/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_bank_2/0001/Bank?$top=10
Authorization: Basic [SAPのID]:[PW]
普通はIDPWをエンコードしたりするものでしょうが、今回は動確なので割愛します。
上記URLとHTTPパラメータでリクエストします。
ちゃんと結果が返ってきますね。
では今度は登録をやってあげます。
内部で動確したときと同様、BASIC認証するためAuthorizationタグをつけてPOSTしてみましょう。
POST httpshttps:[RootURL]/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_bank_2/0001/Bank
Authorization: Basic [SAPのID]:[PW]
content-type: application/json
{
"BankCountry": "JP",
"BankInternalID": "0006005",
"BankName": "TESTBANK",
"Region": "27"
}
すると結果は、↓
HTTP/1.1 403 Forbidden
content-type: text/plain; charset=utf-8
content-length: 21
x-csrf-token: Required
sap-server: true
sap-perf-fesrec: XXXX.000000
CSRF token is missing
403が返ってきました。
これはCSRFトークンがリクエストに付与されていないためです。
先程内部からPOSTした時はSAP Gateway Clientのほうがかってにトークンをつけてくれたのですが、外部から動確する時はHTTPリクエストにトークンをつけなければなりません。
↑のリンクを参考に、POSTする前にトークンをGETします。(URLは同じでいいです。)
GET https://https:[RootURL]/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_bank_2/0001/Bank
Authorization: Basic [SAPのID]:[PW]
X-CSRF-Token: Fetch
HTTP/1.1 200 OK
content-type: application/json;odata.metadata=minimal;charset=utf-8
content-length: 1498
x-csrf-token: [CSRFトークン]
odata-version: 4.0
レスポンスのx-csrf-tokenにトークンが入っているので、返ってきたトークンをPOSTに付与して、もう一度Requestします。
POST https:[RootURL]/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_bank_2/0001/Bank
Authorization: Basic [SAPのID]:[PW]
content-type: application/json
X-CSRF-Token: [CSRFトークン]
Cookie:
{
"BankCountry": "JP",
"BankInternalID": "0006005",
"BankName": "TESTBANK",
"Region": "27"
}
HTTP/1.1 201 Created
content-type: application/json;odata.metadata=minimal;charset=utf-8
content-length: 341
location: Bank(BankCountry='JP',BankInternalID='0006005')
odata-version: 4.0
cache-control: no-cache, no-store, must-revalidate
sap-server: true
sap-perf-fesrec: XXXXXXX
{
"@odata.context": "$metadata#Bank/$entity",
"@odata.metadataEtag": "W/\"20220727003513\"",
"BankCountry": "JP",
"BankInternalID": "0006005",
"BankName": "TESTBANK",
"Region": "27",
"ShortStreetName": "",
"ShortCityName": "",
"SWIFTCode": "",
"BankNetworkGrouping": "",
"IsMarkedForDeletion": false,
"Bank": "",
"BankBranch": "",
"BankCategory": "",
"SAP__Messages": []
}
201が返ってきましたね。
↓の通り、ちゃんとDBに登録できてます。
以上です。
参考