SAP ODataのメタデータはWeb APIの仕様書

ODataにSE37はあるのか代わりはメタデータ

「このOData、何ができるAPIなんだろう?」

SAPの開発・導入に関わるエンジニアなら、一度はそう思ったことがあるはずだ。

BAPIであれば、トランザクションSE37を開けば話は早かった。関数モジュール名を入力してEnterを押せば、パラメータの型も、テーブルの構造も、一覧で確認できた。

ところがSAP ODataWeb API)の世界では、SE37に相当するトランザクションは存在しない。
「このAPIはどうやって使うんだ?」と途方に暮れるSAPエンジニアは少なくない。

答えは、OData自身が持つ「設計図」にある。それがOData APIの「メタデータ($metadata)だ。
ブラウザで特定のURLにアクセスするだけで、そのAPIの全貌を見ることができる。

本記事は、BAPIとSE37に慣れたSAPエンジニアを対象に、ODataのメタデータを参照する方法を解説する。

なお、OData APIの例として、購買発注伝票登録を行う標準API「C_PURCHASEORDER_FS_SRV」(V2)と「API_PURCHASEORDER_2(V4)を取り上げる。

目次

ABAPエンジニアが戸惑うこと ― ODataにSE37はない

BAPIならSE37で確認できた

SAPのBAPIを使った開発では、T-Code: SE37(Function Builder)が頼りになる相棒だった。
たとえば購買発注を登録するBAPI「BAPI_PO_CREATE1」を調べるとき、SE37で関数名を入力すれば、以下の情報がすべて画面上で確認できた。

  • Import パラメータ:呼び出し時に渡す入力値とその型
  • Export パラメータ:処理結果として返ってくる値
  • Tables パラメータ:明細データなど、テーブル形式でやり取りする構造体
  • ドキュメント:パラメータの説明文

言うなれば、SE37はBAPIの「仕様書閲覧ツール/テストツール」そのものだ。
開発者はSE37を見ながらABAPコードを書き、テストも同じ画面から実行できた。これは非常に強力な開発環境だ。

SE37があったからこそ、SAPエンジニアはBAPIの仕様を短時間で把握し、開発に集中できていた。
その「当たり前」が、ODataの世界では通用しない。

ODataの場合はどこを見ればいいのか?

SAP S/4HANAやSAP BTPの時代になり、外部システムとのインターフェースの主役はOData(Web API)へと移行しつつある。IDocやRFC接続に代わり、RESTfulなWeb APIで連携するケースが増えている。

しかし、SE37のような「APIの仕様書を一覧表示するGUI」はODataには存在しない。SAPが提供する開発ツール(SAP Gateway、SEGW、Business Accelerator Hub)である程度の情報は確認できるが、現場のエンジニアが手早く「このAPIで何ができるか」を調べるには、OData自身が持つメタデータを直接参照するのが最も確実だ。

ODataには、APIの構造を自己記述する仕組みが標準で備わっている。それが$metadataエンドポイントだ。
これを使いこなすことが、OData時代のSAPエンジニアに求められる基本スキルとなる。


OData API の探し方や、Business Accelerator Hub の使い方について解説した記事は以下。

まずはAPIの存在確認

まず、OData API そのものが利用中のS/4に存在するかを確認する。

OData API では以下のT-CDを利用してAPIの存在や有効かどうかを確認できる。APIのバージョンによって使い分けなければならない点が少々面倒だ。

OData APIの登録・有効化を行うT-CD
  • V2の場合: /IWFND/MAINT_SERVICE
  • V4の場合: /IWBEP/V4_ADMIN

コマンドボックスからT-CDを呼び出す際は、次のように「/n」を先頭に付けて呼び出す。

/n/IWBEP/V4_ADMIN

購買発注APIもV2とV4で分かれており、それぞれ以下の通り。

購買発注のOData API
  • V2: API_PURCHASEORDER_PROCESS_SRV
  • V4: API_PURCHASEORDER_2

V2の API_PURCHASEORDER_PROCESS_SRV については、登録済みの購買伝票を取得するサンプルを、ABAP版とExcelマクロ版それぞれ以下の記事で公開している。是非参考にしてほしい。


OData APIを有効化する手順について解説した記事は以下。

APIのサービスドキュメント

APIのサービスドキュメントとは

その OData API が何者なのかは、APIのサービスドキュメントを参照すればよい。

APIのサービスドキュメント

  • そのAPIでアクセスできるデータの入口(エンティティセット)の一覧

APIのサービスドキュメントをBAPIおよびSE37にたとえると、以下のようなイメージだ。

OData APIBAPIにたとえるとSE37でいうと
サービスドキュメントOData APIの中身の一覧IMPORT/EXPORT/TABLE など、どの「タブ」が存在しているか俯瞰しているイメージ
エンティティセットデータ単位(ヘッダ・明細など)どのようなIMPORT(ヘッダ)/EXPORT(出力項目)/TABLE(明細)が実装されているかを確認する
$metadataインターフェース定義パラメータ+型定義(SE37の詳細画面

APIをブラウザで叩いてみる

ブラウザのURLにAPIを指定して叩くと、APIのサービスドキュメントを参照できる。
たとえば購買発注APIの場合、以下のURLでAPIを指定すれば、サービスドキュメントを呼び出すことができる。

V2: C_PURCHASEORDER_FS_SRV の場合

https://<ホスト(:ポート)>/sap/opu/odata/sap/C_PURCHASEORDER_FS_SRV/

V2のデフォルト書式はXMLのため、上記のURLで表示されるサービスドキュメントはXML形式である。
JSON形式など書式を指定するには ?$format を指定する。

https://<ホスト(:ポート)>/sap/opu/odata/sap/C_PURCHASEORDER_FS_SRV/?$format=json

{
	"d": {
		"EntitySets": [
			"C_BR_CFOPCategoryValHelp",
			"C_BR_MaterialOriginValHelp",
			"C_BR_MaterialUsageValHelp",
			"C_BR_NCMValHelp",
			"C_IN_GSTControlCodeValueHelp",
			"C_MM_CompanyCodeValueHelp",
			"C_MM_CountryValueHelp",
			"C_MM_IncotermValueHelp",
			"C_MM_MaterialGroupValueHelp",
			"C_MM_MaterialValueHelp",
			"C_MM_PlantValueHelp",
			"C_MM_ProductTypeValueHelp",
			"C_MM_RegionValueHelp",
			"C_MM_ServicePerformerValueHelp",
			"C_MM_StorLocValueHelp",
			"C_MM_SupplierValueHelp",
			"C_POAccountAssignmentFactSheet",
			"C_PODeliveryAddressFactSheet",
			"C_POMntnTaxCountryValueHelp",
			"C_POScheduleLineFactSheet",
			"C_POSupplierAddressFactSheet",
			"C_PurchaseContractValHelp",
			"C_PurchaseOrderFactSheetNote",
			"C_PurchaseOrderFs",
			"C_PurchaseOrderGoodsReceipt",
			"C_PurchaseOrderItemNoteType",
			"C_PurchaseOrderLimitItem",
			"C_PurchaseOrderNoteType",
			"C_PurchasingDeliveryAddressVH",
			"C_PurchasingGroupValueHelp",
			"C_PurchasingOrgValueHelp",
			"C_PurgCustomerBPShipToAddrVH",
			"C_PurOrdActACatValHelp",
			"C_PurOrderItemFactSheetNote",
			"C_PurOrderItemHierFactSheet",
			"C_PurOrderPartnerFactSheet",
			"C_PurOrdHierItmCatValueHelp",
			"C_PurOrdIntrastatCmmdtyCodeVH",
			"C_PurOrdIntrastatSrvcCodeVH",
			"C_PurOrdItemCO2eqFootprint",
			"C_PurOrdItemEnh",
			"C_PurOrdItmCatValHelp",
			"C_PurOrdRefPurConItm",
			"C_PurOrdSuplrConfDisplay",
			"C_PurOrdTaxJurisdictionValHelp",
			"C_PurOrdWBSValHelp",
			"C_PurReqItemByPurOrder",
			"C_SuplInvPurOrdRef",
			"C_SupplierPurchOrgVH",
			"I_AcctAssignmentCategoryText",
			"I_Address",
			"I_AssetClassStdVH",
			"I_AssetClassText",
			"I_BatchVH",
			"I_BPCustomerMultiAddrVH",
			"I_BudgetPeriodStdVH",
			"I_BusinessAreaStdVH",
			"I_BusinessPartner",
			"I_BusinessPartnerSuplrCo",
			"I_BusinessPartnerVH",
			"I_BusinessUserVH",
			"I_ChartOfAccountsStdVH",
			"I_ChartOfAccountsText",
			"I_CommitmentItemStdVH",
			"I_CompanyCode",
			"I_CompanyCodeStdVH",
			"I_ControllingArea",
			"I_ControllingAreaStdVH",
			"I_CostCenterText",
			"I_CostCenterVH",
			"I_CountryText",
			"I_CountryVH",
			"I_CreditControlAreaStdVH",
			"I_Currency",
			"I_CurrencyStdVH",
			"I_Customer_VH",
			"I_EarmarkedFundsDocEntryStatus",
			"I_EarmarkedFundsDocTypeStdVH",
			"I_EarmarkedFundsDocumentStdVH",
			"I_EarmarkedFunds_DocCategory",
			"I_EmrkdFndsDocumentItemStdVH",
			"I_EngmntProjSrvcOrgStdVH",
			"I_FixedAsset",
			"I_FndsMgmtFuncnlAreaStdVH",
			"I_FormOfAddressText",
			"I_FunctionalAreaText",
			"I_FundedProgramStdVH",
			"I_FundsCenterStdVH",
			"I_FundStdVH",
			"I_GLAccountStdVH",
			"I_GLAccountText",
			"I_GoodsMovementType",
			"I_GrantStdVH",
			"I_IncotermsClassification",
			"I_IncotermsClassificationText",
			"I_InternalOrderStdVH",
			"I_Language",
			"I_MasterFixedAsset",
			"I_MasterFixedAssetStdVH",
			"I_Material",
			"I_MaterialGroup",
			"I_MaterialGroupText",
			"I_MaterialStdVH",
			"I_MaterialText",
			"I_MaterialType",
			"I_MM_CostCenterValueHelp",
			"I_MM_GLAccountVH",
			"I_PartnerFunction",
			"I_PartnerFunctionText",
			"I_PaymentTerms",
			"I_PaymentTermsText",
			"I_Plant",
			"I_Producttype",
			"I_ProductTypeCodeText",
			"I_ProfitCenterStdVH",
			"I_ProfitCenterText",
			"I_ProjectNetwork",
			"I_ProjectNtwkValueHelp",
			"I_PurchaseContractItemStdVH",
			"I_PurchaseOrder",
			"I_PurchaseOrderEnhanced",
			"I_PurchaseOrderItem",
			"I_PurchaseOrderItemStdVH",
			"I_PurchaseOrderScheduleLine",
			"I_PurchaseOrderStatusValueHelp",
			"I_PurchaseOrderStdVH",
			"I_PurchasingDocumentStatus",
			"I_PurchasingDocumentStatusText",
			"I_PurchasingDocumentType",
			"I_PurchasingDocumentTypeText",
			"I_PurchasingGroup",
			"I_PurchasingInfoRecordStdVH",
			"I_PurchasingOrganization",
			"I_PurgDocumentItemCategoryText",
			"I_PurOrderPartnerFunctionVH",
			"I_Shippinginstructiontext",
			"I_StorageLocation",
			"I_Supplier",
			"I_SupplierConfControlKey",
			"I_Supplier_VH",
			"I_TaxCalculationProcedure",
			"I_TaxCode",
			"I_TaxJurisdiction",
			"I_TransportationLocationType",
			"I_TransportationLocationVH",
			"I_UnitOfMeasure",
			"I_User",
			"I_WBSElementBasicDataStdVH",
			"SAP__FormatSet",
			"SAP__PDFStandardSet",
			"SAP__TableColumnsSet",
			"SAP__CoverPageSet",
			"SAP__SignatureSet",
			"SAP__HierarchySet",
			"SAP__PDFHeaderSet",
			"SAP__PDFFooterSet",
			"SAP__ValueHelpSet",
			"SAP__Currencies",
			"SAP__UnitsOfMeasure",
			"SAP__MyDocumentDescriptions",
			"SAP__FileShareSet"
		]
	}
}

V4: API_PURCHASEORDER_2 の場合

https://<ホスト(:ポート)>/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_purchaseorder_2/0001/

このURLをブラウザで叩くと、以下のようなサービスドキュメントをJSON形式で取得できる。

{
	"@odata.context": "$metadata",
	"value": [
		{
			"name": "POItemReturnNextPlant",
			"url": "POItemReturnNextPlant"
		},
		{
			"name": "POSubcontractingComponent",
			"url": "POSubcontractingComponent"
		},
		{
			"name": "PurchaseOrder",
			"url": "PurchaseOrder"
		},
		{
			"name": "PurchaseOrderAccountAssignment",
			"url": "PurchaseOrderAccountAssignment"
		},
		{
			"name": "PurchaseOrderInvoicingPlan",
			"url": "PurchaseOrderInvoicingPlan"
		},
		{
			"name": "PurchaseOrderInvoicingPlanItem",
			"url": "PurchaseOrderInvoicingPlanItem"
		},
		{
			"name": "PurchaseOrderItem",
			"url": "PurchaseOrderItem"
		},
		{
			"name": "PurchaseOrderItemNote",
			"url": "PurchaseOrderItemNote"
		},
		{
			"name": "PurchaseOrderItemReturn",
			"url": "PurchaseOrderItemReturn"
		},
		{
			"name": "PurchaseOrderNote",
			"url": "PurchaseOrderNote"
		},
		{
			"name": "PurchaseOrderPartner",
			"url": "PurchaseOrderPartner"
		},
		{
			"name": "PurchaseOrderScheduleLine",
			"url": "PurchaseOrderScheduleLine"
		},
		{
			"name": "PurchaseOrderSupplierAddress",
			"url": "PurchaseOrderSupplierAddress"
		},
		{
			"name": "PurOrderItemDeliveryAddress",
			"url": "PurOrderItemDeliveryAddress"
		},
		{
			"name": "PurOrderItemPricingElement",
			"url": "PurOrderItemPricingElement"
		}
	]
}

ここでは

"name": "PurchaseOrder"
"name": "PurchaseOrderItem"

がエンティティセットであり、”PurchaseOrder” は購買発注ヘッダ、”PurchaseOrderItem” は購買発注明細に該当する。
この感覚は、BAPI_PO_CREATE1 における ”POHEADER” と “POITEM” と同じだ。

なお、V4のサービスドキュメント書式はJSONに固定されているため、$format による書式指定はできない。

ODataの仕様書:メタデータを覗いてみる

OData API のメタデータ($metadata)とは

SAPのOData APIにおけるメタデータは、BAPIにおけるインターフェースをXMLで表現したものと捉えると分かりやすい。

BAPIではSE37でパラメータやデータ構造を確認していたが、ODataでは$metadataを参照することで、エンティティ(構造)、プロパティ(フィールド)、キー項目などを把握できる。
つまり、メタデータはAPIの仕様書そのもの なのだ。

対応関係はシンプルで、エンティティ=構造、エンティティセット=内部テーブル、CRUD操作=BAPIの処理種別に相当する。

なお、メタデータは OData API をSAP Gatewayでサービス公開時に自動生成される。

ブラウザでメタデータを参照する

ODataのメタデータは、ブラウザだけで確認できる。特別なツールは不要だ。SAP S/4HANA(オンプレまたはCloud)にアクセスできる環境があれば、URLを入力するだけでよい。

たとえば購買発注APIの場合、以下のURLで呼び出すことが可能だ。
V2もV4も、API名称の後に「$metadata」を追加するだけである。

V4: API_PURCHASEORDER_2 の場合

https://<ホスト(:ポート)>/sap/opu/odata4/iwbep/all/srvd_a2x/sap/api_purchaseorder_2/0001/$metadata

BAPIの世界に置き換えると、$metadataは「SE37の全パラメータ定義+構造体定義(SE11)をXMLで書き出したもの」と考えると理解しやすい。

検索・登録・更新・削除の区別は?

BAPIであれば、検索・登録・更新・削除といったデータの操作方法は、汎用モジュール単位に明確に分かれていた。
購買伝票の場合、検索なら BAPI_PO_GETDETAIL、登録なら BAPI_PO_CREATE1、変更なら BAPI_PO_CHANGE … といった具合に、名称によっておよその用途がわかった。

一方、OData API の場合はどうか?
$metadataを読み込んでも、そのAPIが検索・登録・更新・削除のどの機能に対応しているのか、判別はできない。

それもそのはずで、ODataは検索・登録・更新・削除でAPIを分けていない

HTTPメソッド:検索・登録・更新・削除を指定

BAPIとODataでは、設計思想に大きな違いがある。
OData API は機能別にAPIが用意されているわけではなく、基本的にはデータ構造が定義されているだけだ。

  • BAPI: データに対する操作(検索・登録・更新・削除)
  • OData: データ構造の定義(メタデータ)

ODataでは、HTTPメソッドが検索・登録・更新・削除の役割を担う
つまり、APIを呼び出す際に、メソッドによってデータの操作方法を指定する。

各メソッドとCRUD操作の対応は以下の通りだ。

HTTPメソッド操作BAPIでのイメージ
GET検索・照会BAPI_PO_GETDETAIL
POST登録・新規作成BAPI_PO_CREATE1
PUT / PATCH更新(全項目/差分)BAPI_PO_CHANGE
DELETE削除BAPI_PO_CHANGE(削除フラグ)

まとめ:SAP ODataの$metadataはSE37の代わり

OData API の$metadaは、Web APIの仕様書そのものであり、Webブラウザだけで呼び出せることを解説した。

また、BAPIでは検索・登録・更新といった処理ごとに汎用モジュールが分かれている。一方、OData API は機能別にAPIが用意されているわけではなく、基本的にはデータ構造が定義されているだけだ。ここが大きな違いである。

BAPIでいう検索・登録・更新は、OData API では API 呼び出し時の HTTP メソッド、つまり GET・POST・PUT などによって制御される。この点も、BAPIに慣れているABAPエンジニアにとっては、考え方をアップデートすべき大きな変化点であり、最初は戸惑うかもしれない。

しかし、SE37で培った「構造を読む目」はそのまま活きる。$metadata は SE37 の代わりになる。そう理解した瞬間から、ODataへの抵抗感は一気に減るはずだ。

次回の記事では、$metadata についてさらに踏み込み、XMLタグを読み取りながら、APIのデータ構造を解読する方法を具体的に解説する。BAPIに慣れたABAPエンジニアが、SE37+SE11でデータ構造を理解し、プログラムを設計・開発するのと同じように OData API を扱えるようになることを目標に、丁寧に解説していく。乞うご期待。


よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次