1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SAP Cloud SDK for JavaScriptを使ってみる (2)サービスの作成

Posted at

##はじめに
この記事は、SAP Cloud SDK for JavaScriptを使ってみるシリーズの2回目です。この記事では、SAP Cloud SDK を使ってサービスを開発する手順について説明します。

ベースとするのは以下のチュートリアルです。

チュートリアルでは、S/4HANAのOData APIであるBusiness Partnerを使い、SAP Cloud SDKのOData Clientの使い方を確認します。OData Clientの使い方自体はチュートリアルで詳しく説明されていますので、そちらを参考にしてください。
この記事では、NestJSのCLIを使って必要なファイルを作る方法について説明します。

##事前準備
テストで使えるS/4HANAの環境がない場合、接続先としては以下のオプションがあります。
①API Business Hub
②モックのBusiness Partner Serviceをローカルに作成
今回は、テストを行う都合上、結果が一定になる②の方法を選択します。

モックのBusiness Partner Serviceの作り方については、以下に書いてあります。
https://sap.github.io/cloud-s4-sdk-book/pages/mock-odata.html

簡単に説明すると、

  • GitHubのブランチmock-serverをチェックアウト
git clone https://github.com/SAP/cloud-s4-sdk-book
cd cloud-s4-sdk-book
git checkout mock-server
  • モックサーバーを起動
npm i
npm start

http://localhost:3000/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartnerにアクセスすると以下のようにデータが表示されます。
image.png

##ステップ

  1. プロジェクトを生成
  2. Module、Controller、Serviceを生成
  3. Business Partner取得のロジックを実装
  4. Cloud Foundryにデプロイ

###1. プロジェクトを生成
前提:npm install -g @sap-cloud-sdk/cliでSAP Cloud SDK CLIがインストールされていること

####1.1. プロジェクトを生成

sap-cloud-sdk init my-sdk-project

一つ目の質問(nest.jsのプロジェクトをターゲットのディレクトリで初期化するか)にはyを選択します。
二つ目の質問(usage analyticsを提供するか)にはyまたはnを選択します。

The target directory (my-sdk-project) does not contain a `package.json.`
Should a new `nest.js` project be initialized in the target directory? (y|n): y
Building application scaffold... done
Enter project name (for use in manifest.yml) [my-sdk-project]: 
Do you want to provide anonymous usage analytics to help us improve the SDK? (y|n): y

最終的に以下の画面が表示されます。

+--------------------------------------------------------------+
 ✅ Init finished successfully.

 🚀 Next steps:
 - Run the application locally (`npm run start:dev`)
 - Deploy your application (`npm run deploy`)

 🔨 Consider setting up Jenkins to continuously build your app.
 Use `sap-cloud-sdk add-cx-server` to create the setup script.
+--------------------------------------------------------------+

####1.2. src/main.jsを変更
デフォルトでは、生成されたアプリケーションはポート3000で動くようになっていますが、モックサーバーをポート3000で実行している都合で、ポートを8080に変更します。

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT || 3000); //->8080に変更
}
bootstrap();

####1.3. 実行してみる
ターミナルにnpm run start:devと入力し、ブラウザでhttp://localhost:8080/を開きます。Hello Worldの画面が表示されればOKです。
image.png

###2. Module、Controller、Serviceを生成
続いて、Module、Controller、Serviceを生成します。Module、Controller、Serviceの関係については前回の記事をご参照ください。

####2.1. Moduleを生成
以下のコマンドでModuleを生成します。

nest generate module business-partner

srcフォルダの配下にbusiness-partnerというフォルダとモジュールができました。
image.png
app.module.tsのimportsにBusinessPartnerModuleが追加されます。

src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { BusinessPartnerModule } from './business-partner/business-partner.module';

@Module({
  imports: [BusinessPartnerModule], //自動で追加される
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

####2.2. Controllerを生成
以下のコマンドでControllerを生成します。

nest generate controller business-partner

business-partnerフォルダ配下にcontrollerとつくファイルが2つ追加されました。このうち、spec.tsはユニットテストで使うためのファイルです。
image.png
business-partner.module.tsにControllerが自動で追加されました。

src/business-partner/business-partner.module.ts
import { Module } from '@nestjs/common';
import { BusinessPartnerController } from './business-partner.controller';

@Module({
  controllers: [BusinessPartnerController]
})
export class BusinessPartnerModule {}

####2.3. Serviceを生成
以下のコマンドでServiceを生成します。

nest generate service business-partner

serviceとつくファイルが2つ追加されました。
image.png

business-partner.module.tsにServiceが自動で追加されました。

src/business-partner/business-partner.module.ts
import { Module } from '@nestjs/common';
import { BusinessPartnerController } from './business-partner.controller';
import { BusinessPartnerService } from './business-partner.service';

@Module({
  controllers: [BusinessPartnerController],
  providers: [BusinessPartnerService]
})
export class BusinessPartnerModule {}

###3. Business Partner取得のロジックを実装
SAP Cloud SDKのOData Clientを使い、Business Partnerを取得します。

####3.1. @sap/cloud-sdk-vdm-business-partner-serviceをインストール
以下のコマンドでBusiness PartnerのODataサービスにアクセスするためのライブラリをインストールします。

npm i @sap/cloud-sdk-vdm-business-partner-service

####3.2. Serviceの実装
Serviceに以下のロジックを実装します。

src/business-partner/business-partner.service.ts
import { Injectable } from '@nestjs/common';
import { BusinessPartner } from '@sap/cloud-sdk-vdm-business-partner-service'

@Injectable()
export class BusinessPartnerService {
    getAllBusinessPartners(): Promise<BusinessPartner[]> {
        return BusinessPartner.requestBuilder()
            .getAll()
            .execute({
                destinationName: 'MockServer'
            })
    }
}

ここでは以下のことを行っています。

  • @sap/cloud-sdk-vdm-business-partner-serviceからBusinessPartnerをインポート(2行目)
  • getAllBusinessPartnersメソッドでBusiness Partnerを取得
    • GetAll Request Builderで全てのエンティティを取得するリクエストを作成
    • executeでHTTPリクエストを実行

executeについて
executeメソッドにはDestinationオブジェクト、またはDestinationNameAndJwtオブジェクトを渡します。上の例では、BTPのDestinationを使用するためDestinationNameAndJwtを使用しています。URLを直接指定する場合はDestinationオブジェクトを使い以下のようにURLを設定します。

            .execute({
                url: 'http://localhost:3000'
            })

ローカル実行のための設定
ローカル実行時にDestinationが取得できるように、以下の設定を行います。

①.envファイルを作成
プロジェクトのルートに.envファイルを作成し、Destinationの設定をします。

.env
destinations=[{"name": "MockServer", "url": "http://localhost:3000"}]

@nestjs/configをインストール

npm i @nestjs/config

③ConfigModuleをapp.mocule.tsに追加
.envファイルが環境変数として使用されるように、@nestjs/configのConfigModuleをapp.mocule.tsに追加します。

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config'; //追加
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { BusinessPartnerModule } from './business-partner/business-partner.module';

@Module({
  imports: [ConfigModule.forRoot(), BusinessPartnerModule], //追加

####3.3. Controllerの実装
Controllerに以下のロジックを実装します。

src/business-partner/business-partner.controller.ts
import { Controller, Get } from '@nestjs/common';
import { BusinessPartnerService } from './business-partner.service';
import { BusinessPartner } from '@sap/cloud-sdk-vdm-business-partner-service'

@Controller('business-partner')
export class BusinessPartnerController {
    constructor(private readonly businessPartnerService: BusinessPartnerService) {}

    @Get()
    getAllBusinessPartners(): Promise<BusinessPartner[]> {
        return this.businessPartnerService.getAllBusinessPartners();
    }
}

ここでは以下のことを行っています。

  • @nestjs/commonからControllerおよびGetをインポート
  • @sap/cloud-sdk-vdm-business-partner-serviceからBusinessPartnerをインポート
  • BusinessPartnerControllerクラスのコンストラクタでBusinessPartnerServiceを使用することを宣言(※)
  • getAllBusinessPartnersメソッドでBusinessPartnerServiceのgetAllBusinessPartnersメソッドを呼ぶ

※これにより、実行時にNestJSが自動的にBusinessPartnerServiceをインスタンス化して挿入してくれる。このことをDependency Injectionという。この仕組みのおかげで、Unit Testで依存先のモジュールをテスト用のモジュールに簡単に置き換えることができる。

Controller、Getについて
これらはいずれもstring型のパスを引数に取ることができます。
Controllerで指定したパスがリクエストのベースパスに一致する場合、そのControllerで処理が行われます。同様に、Getで指定したパスがベースパスの次のパスに一致する場合、そのGetの下のメソッドで処理が行われます。
以下の例では、/business-partners/getAllというリクエストがgetAllBusinessPartnersメソッドで処理されます。

@Controller('business-partner')
export class BusinessPartnerController {
    constructor(private readonly businessPartnerService: BusinessPartnerService) {}

    @Get('getAll')
    getAllBusinessPartners(): Promise<BusinessPartner[]> {
        return this.businessPartnerService.getAllBusinessPartners();
    }
}

####3.4. 実行してみる
ブラウザにhttp://localhost:8080/business-partnerと入力します。
以下の画面が表示されればOKです。
image.png

####3.4. 追加のクエリオプションの指定
OData Clientでは、select, filter, top skipなどのクエリオプションを指定することも可能です。

以下のチュートリアル、およびドキュメントを参照して、クエリオプションを試してみてください。

###4. Cloud Foundryにデプロイ
####4.1. Destinationを使用するための設定
事前準備で作成したモックのBusiness Partner ServiceをCloud Foundryにデプロイし、Destinationとして登録します。デプロイ、およびDestinationの登録手順については以下のチュートリアルのStep2~4をご参照ください。

Deploy Application to Cloud Foundry with SAP Cloud SDK for JavaScript

####4.2. Cloud Foundryにデプロイ
Cloud Foundryにデプロイするためには、package.jsonに定義されたdeployスクリプトを実行します。

npm run deploy

deployスクリプトは以下のように3つのコマンドから成っています。

    "deploy": "npm run build && sap-cloud-sdk package && cf push",

各コマンドは次のことを行います。

npm run build
distフォルダにビルドした結果のファイルを格納する。
image.png

sap-cloud-sdk package
deploymentフォルダにdistフォルダ、およびpackage.json、package-lock.jsonをコピーする。
image.png

cf push
manifest.ymlの内容に従い、アプリケーションをCloud Foundryにデプロイする。
manifest.ymlでは、deployment配下のものをデプロイする設定になっている。

manifest.yml
applications:
  - name: my-sdk-project
    path: deployment/
    buildpacks:
      - nodejs_buildpack
    memory: 256M
    command: npm run start:prod
    random-route: true
    services:
      - my-destination    
      - my-xsuaa
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?