Technical Articles
SAP Cloud SDK for JavaScriptでオンプレOData呼出
SAP Cloud SDK for JavaScriptを使ってオンプレのODataを呼び出すメモです。「SAP Cloud SDK for JavaScriptを使ってSAP CP CFへアプリをデプロイ」に基本的なことを書いています。
「Generate Custom OData Client Library with SAP Cloud SDK’s Generator」の内容を少し変えています。
プログラムはGitHubに置いています。
開発環境
以下の環境で実行しています。
- OS: Ubuntu18.04.01 LTS
- Node.js: 12.14.1
- npm: 6.13.4
- CF cli: 6.49.0+d0dfa93bb.2020-01-07
- SAP Cloud SDK for JavaScript:1.16
手順
前提
「SAP Cloud SDK for JavaScriptを使ってSAP CP CFへアプリをデプロイ」の「1. プロジェクトの作成」から「2. プロジェクト作成確認」まで実行済の前提。
1. cloud-sdk-generatorのインストール
npmでcloud-sdk-generatorのインストール
npm install --save-dev @sap/cloud-sdk-generator
2. “service-specifications”フォルダ作成とxmlファイル取得
今回はS/4 HANAのODataを呼び出すので、S/4 HANAにログインしてメタデータを照会します。「Generate .edmx and/or .xml file for Fiori App developed using SAP Web IDE」を参考にしました。
保存先ディレクトリとして”service-specifications”フォルダをプロジェクト直下に作っておきます。今回は得意先のODataである”CB_CUSTOMER_SRV”を使うので以下のURLにブラウザでアクセスして、”cb_customer_srv.xml”として保存します。
http://<host>:<port>/sap/opu/odata/sap/CB_CUSTOMER_SRV/$metadata/
3. OData Client Libraryの生成
以下のコマンドでOData Client Libraryを生成します。”odata-client”というフォルダが出力先として生成されます。
npx generate-odata-client --inputDir service-specifications --outputDir odata-client --forceOverwrite
フォルダの中身を確認します。
$ ls odata-client/cb-customer-service/
BatchRequest.d.ts Contact_PersoNsRequestBuilder.js Customer_Comp_CodEsRequestBuilder.js.map Customer_Sales_AreAsRequestBuilder.ts SalesContracts.js.map SalesOrdersRequestBuilder.d.ts
BatchRequest.d.ts.map Contact_PersoNsRequestBuilder.js.map Customer_Comp_CodEsRequestBuilder.ts Customer_Sales_AreAs.ts SalesContractsRequestBuilder.d.ts SalesOrdersRequestBuilder.d.ts.map
BatchRequest.js Contact_PersoNsRequestBuilder.ts Customer_Comp_CodEs.ts Customers.d.ts SalesContractsRequestBuilder.d.ts.map SalesOrdersRequestBuilder.js
BatchRequest.js.map Contact_PersoNs.ts Customer_Project_Hs.d.ts Customers.d.ts.map SalesContractsRequestBuilder.js SalesOrdersRequestBuilder.js.map
BatchRequest.ts Customer_Bank_AccouNs.d.ts Customer_Project_Hs.d.ts.map Customers.js SalesContractsRequestBuilder.js.map SalesOrdersRequestBuilder.ts
BillingDocuments.d.ts Customer_Bank_AccouNs.d.ts.map Customer_Project_Hs.js Customers.js.map SalesContractsRequestBuilder.ts SalesOrders.ts
BillingDocuments.d.ts.map Customer_Bank_AccouNs.js Customer_Project_Hs.js.map CustomersRequestBuilder.d.ts SalesContracts.ts SalesQuotations.d.ts
BillingDocuments.js Customer_Bank_AccouNs.js.map Customer_Project_HsRequestBuilder.d.ts CustomersRequestBuilder.d.ts.map SalesGroupContracts.d.ts SalesQuotations.d.ts.map
BillingDocuments.js.map Customer_Bank_AccouNsRequestBuilder.d.ts Customer_Project_HsRequestBuilder.d.ts.map CustomersRequestBuilder.js SalesGroupContracts.d.ts.map SalesQuotations.js
BillingDocumentsRequestBuilder.d.ts Customer_Bank_AccouNsRequestBuilder.d.ts.map Customer_Project_HsRequestBuilder.js CustomersRequestBuilder.js.map SalesGroupContracts.js SalesQuotations.js.map
BillingDocumentsRequestBuilder.d.ts.map Customer_Bank_AccouNsRequestBuilder.js Customer_Project_HsRequestBuilder.js.map CustomersRequestBuilder.ts SalesGroupContracts.js.map SalesQuotationsRequestBuilder.d.ts
BillingDocumentsRequestBuilder.js Customer_Bank_AccouNsRequestBuilder.js.map Customer_Project_HsRequestBuilder.ts Customers.ts SalesGroupContractsRequestBuilder.d.ts SalesQuotationsRequestBuilder.d.ts.map
BillingDocumentsRequestBuilder.js.map Customer_Bank_AccouNsRequestBuilder.ts Customer_Project_Hs.ts index.d.ts SalesGroupContractsRequestBuilder.d.ts.map SalesQuotationsRequestBuilder.js
BillingDocumentsRequestBuilder.ts Customer_Bank_AccouNs.ts Customer_Sales_AreAs.d.ts index.d.ts.map SalesGroupContractsRequestBuilder.js SalesQuotationsRequestBuilder.js.map
BillingDocuments.ts Customer_Comp_CodEs.d.ts Customer_Sales_AreAs.d.ts.map index.js SalesGroupContractsRequestBuilder.js.map SalesQuotationsRequestBuilder.ts
Contact_PersoNs.d.ts Customer_Comp_CodEs.d.ts.map Customer_Sales_AreAs.js index.js.map SalesGroupContractsRequestBuilder.ts SalesQuotations.ts
Contact_PersoNs.d.ts.map Customer_Comp_CodEs.js Customer_Sales_AreAs.js.map index.ts SalesGroupContracts.ts tsconfig.json
Contact_PersoNs.js Customer_Comp_CodEs.js.map Customer_Sales_AreAsRequestBuilder.d.ts package.json SalesOrders.d.ts typedoc.json
Contact_PersoNs.js.map Customer_Comp_CodEsRequestBuilder.d.ts Customer_Sales_AreAsRequestBuilder.d.ts.map SalesContracts.d.ts SalesOrders.d.ts.map
Contact_PersoNsRequestBuilder.d.ts Customer_Comp_CodEsRequestBuilder.d.ts.map Customer_Sales_AreAsRequestBuilder.js SalesContracts.d.ts.map SalesOrders.js
Contact_PersoNsRequestBuilder.d.ts.map Customer_Comp_CodEsRequestBuilder.js Customer_Sales_AreAsRequestBuilder.js.map SalesContracts.js SalesOrders.js.map
4. コントローラ作成とビルド
コントローラを作成し、ビルドします。
フォルダ”src”直下に新たに”customer.controller.ts”を以下のコードで作成します。宛先、ユーザ、パスワードは変更が必要です。
import { Controller, Get, HttpException } from '@nestjs/common';
import { Customers } from '../odata-client/cb-customer-service';
@Controller()
export class CustomerController {
@Get('customer')
getCustomer() {
return getAllCustomers()
.catch(error => {
throw new HttpException(`Failed to get business partners - ${error.mssage} ${error.stack}`, 500);
});
}
}
function getAllCustomers(): Promise<Customers[]> {
return Customers.requestBuilder()
.getAll()
.top(10) // look at the top 10 customers only
.select(Customers.CUSTOMER_NAME)
.execute({
url: 'http://<host>:50000/',
username: '<user>',
password: '<password>'
});
}
SDKが生成済みのapp.module.tsを変更します。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CustomerController } from './customer.controller';
@Module({
imports: [],
controllers: [AppController, CustomerController],
providers: [AppService],
})
export class AppModule {}
※今回はマニュアルで作りましたが、nest cliというものがあって、使うと便利そうです。今回なら”nest g controller customer”でコントローラーを作成できます(フォルダを作るなど少し今回の動きと異なります)。
あとはビルドと起動をします。
npm run ci-build
npm run start:dev
これで、ブラウザから”http://localhost:3000/customer“にアクセスするとODataで取得できたJSONが表示されます。
5. CFへデプロイ
CFにデプロイする前にpackage.jsonの以下の部分を変更します(変更前は”start:prod”: “node dist/main”,)。main.tsはdist/src/mainに置かれるので、こうしています(もっといい方法があるかもしれません)。
"start:prod": "node dist/src/main",
あとはdeployするだけです。
npm run deploy
これでデプロイ先のURLをブラウザで開けば、”/customer”でOData実行結果が表示されます。