Angular対応のIgnite UI for Angularを使ってNetSuite のデータをグリッドに表示
Angularはデータバインディング、ルーティング、サービスなど業務用のモダンWebアプリケーション構築に適しているWebアプリケーションフレームワークです。
この記事ではCData Software Japanが提供するAPI Serverと連携し、取得したデータをAngular対応のIgnite UI for Angularデータグリッドに表示する方法をご紹介します。
NetSuite データ連携について
CData は、Oracle NetSuite のライブデータにアクセスし、統合するための最も簡単な方法を提供します。お客様は CData の接続機能を以下の目的で使用しています:
- Standard、CRM、OneWorld を含む、すべてのエディションの NetSuite にアクセスできます。
- SuiteTalk API(SOAP ベース)のすべてのバージョンと、SQL のように機能し、より簡単なデータクエリと操作を可能にする SuiteQL に接続できます。
- Saved Searches のサポートにより、事前定義されたレポートとカスタムレポートにアクセスできます。
- トークンベースおよび OAuth 2.0 で安全に認証でき、あらゆるユースケースで互換性とセキュリティを確保します。
- SQL ストアドプロシージャを使用して、ファイルのアップロード・ダウンロード、レコードや関連付けのアタッチ・デタッチ、ロールの取得、追加のテーブルやカラム情報の取得、ジョブ結果の取得などの機能的なアクションを実行できます。
お客様は、Power BI や Excel などのお気に入りの分析ツールからライブ NetSuite データにアクセスするために CData ソリューションを使用しています。また、CData Sync を直接使用するか、Azure Data Factory などの他のアプリケーションとの CData の互換性を活用して、NetSuite データを包括的なデータベースやデータウェアハウスに統合しています。CData は、Oracle NetSuite のお客様が NetSuite からデータを取得し、NetSuite にデータをプッシュするアプリを簡単に作成できるよう支援し、他のソースからのデータを NetSuite と統合することを可能にしています。
当社の Oracle NetSuite ソリューションの詳細については、ブログをご覧ください:Drivers in Focus Part 2: Replicating and Consolidating ... NetSuite Accounting Data
はじめに
API Server の設定
以下のリンクからAPI Server の無償トライアルをスタートしたら、セキュアなNetSuite OData サービスを作成していきましょう。
NetSuite への接続
Angular からNetSuite のデータを操作するには、まずNetSuite への接続を作成・設定します。
- API Server にログインして、「Connections」をクリック、さらに「接続を追加」をクリックします。
- 「接続を追加」をクリックして、データソースがAPI Server に事前にインストールされている場合は、一覧から「NetSuite」を選択します。
- 事前にインストールされていない場合は、コネクタを追加していきます。コネクタ追加の手順は以下の記事にまとめてありますので、ご確認ください。
CData コネクタの追加方法はこちら >> - それでは、NetSuite への接続設定を行っていきましょう!
-
NetSuiteへの接続
NetSuite では、2種類のAPI でデータにアクセスできます。どちらのAPI を使用するかは、Schema 接続プロパティで以下のいずれかを選択して指定してください。
- SuiteTalk は、NetSuite との通信に使用されるSOAP ベースの従来から提供されているサービスです。幅広いエンティティをサポートし、INSERT / UPDATE / DELETE の操作も対応しています。ただし、SuiteQL API と比べるとデータの取得速度が劣ります。また、サーバーサイドでのJOIN に対応していないため、これらの処理はCData 製品がクライアントサイドで実行します。
- SuiteQL は、より新しいAPI です。JOIN、GROUP BY、集計、カラムフィルタリングをサーバーサイドで処理できるため、SuiteTalk よりもはるかに高速にデータを取得できます。ただし、NetSuite データへのアクセスは読み取り専用となります。
データの取得のみが目的でしたらSuiteQL をお勧めします。データの取得と変更の両方が必要な場合は、SuiteTalk をお選びください。
NetSuite への認証
CData 製品では、以下の認証方式がご利用いただけます。
- トークンベース認証(TBA)はOAuth1.0に似た仕組みです。2020.2以降のSuiteTalk とSuiteQL の両方で利用できます。
- OAuth 2.0 認証(OAuth 2.0 認可コードグラントフロー)は、SuiteQL でのみご利用いただけます。
- OAuth JWT 認証は、OAuth2.0 クライアント認証フローの一つで、クライアント認証情報を含むJWT を使用してNetSuite データへのアクセスを要求します。
トークンベース認証(OAuth1.0)
トークンベース認証(TBA)は、基本的にOAuth 1.0 の仕組みです。この認証方式はSuiteTalk とSuiteQL の両方でサポートされています。管理者権限をお持ちの方がNetSuite UI 内でOAuthClientId、OAuthClientSecret、OAuthAccessToken、OAuthAccessTokenSecret を直接作成することで設定できます。 NetSuite UI でのトークン作成手順については、ヘルプドキュメントの「はじめに」セクションをご参照ください。
アクセストークンを作成したら、以下の接続プロパティを設定して接続してみましょう。
- AuthScheme = Token
- AccountId = 接続先のアカウント
- OAuthClientId = アプリケーション作成時に表示されるコンシューマーキー
- OAuthClientSecret = アプリケーション作成時に表示されるコンシューマーシークレット
- OAuthAccessToken = アクセストークン作成時のトークンID
- OAuthAccessTokenSecret = アクセストークン作成時のトークンシークレット
その他の認証方法については、ヘルプドキュメントの「はじめに」をご確認ください。
- 接続情報の入力が完了したら、「保存およびテスト」をクリックします。
NetSuiteへの接続
NetSuite では、2種類のAPI でデータにアクセスできます。どちらのAPI を使用するかは、Schema 接続プロパティで以下のいずれかを選択して指定してください。
- SuiteTalk は、NetSuite との通信に使用されるSOAP ベースの従来から提供されているサービスです。幅広いエンティティをサポートし、INSERT / UPDATE / DELETE の操作も対応しています。ただし、SuiteQL API と比べるとデータの取得速度が劣ります。また、サーバーサイドでのJOIN に対応していないため、これらの処理はCData 製品がクライアントサイドで実行します。
- SuiteQL は、より新しいAPI です。JOIN、GROUP BY、集計、カラムフィルタリングをサーバーサイドで処理できるため、SuiteTalk よりもはるかに高速にデータを取得できます。ただし、NetSuite データへのアクセスは読み取り専用となります。
データの取得のみが目的でしたらSuiteQL をお勧めします。データの取得と変更の両方が必要な場合は、SuiteTalk をお選びください。
NetSuite への認証
CData 製品では、以下の認証方式がご利用いただけます。
- トークンベース認証(TBA)はOAuth1.0に似た仕組みです。2020.2以降のSuiteTalk とSuiteQL の両方で利用できます。
- OAuth 2.0 認証(OAuth 2.0 認可コードグラントフロー)は、SuiteQL でのみご利用いただけます。
- OAuth JWT 認証は、OAuth2.0 クライアント認証フローの一つで、クライアント認証情報を含むJWT を使用してNetSuite データへのアクセスを要求します。
トークンベース認証(OAuth1.0)
トークンベース認証(TBA)は、基本的にOAuth 1.0 の仕組みです。この認証方式はSuiteTalk とSuiteQL の両方でサポートされています。管理者権限をお持ちの方がNetSuite UI 内でOAuthClientId、OAuthClientSecret、OAuthAccessToken、OAuthAccessTokenSecret を直接作成することで設定できます。 NetSuite UI でのトークン作成手順については、ヘルプドキュメントの「はじめに」セクションをご参照ください。
アクセストークンを作成したら、以下の接続プロパティを設定して接続してみましょう。
- AuthScheme = Token
- AccountId = 接続先のアカウント
- OAuthClientId = アプリケーション作成時に表示されるコンシューマーキー
- OAuthClientSecret = アプリケーション作成時に表示されるコンシューマーシークレット
- OAuthAccessToken = アクセストークン作成時のトークンID
- OAuthAccessTokenSecret = アクセストークン作成時のトークンシークレット
その他の認証方法については、ヘルプドキュメントの「はじめに」をご確認ください。
API Server のユーザー設定
次に、API Server 経由でNetSuite にアクセスするユーザーを作成します。「Users」ページでユーザーを追加・設定できます。やってみましょう。
- 「Users」ページで ユーザーを追加をクリックすると、「ユーザーを追加」ポップアップが開きます。
-
次に、「ロール」、「ユーザー名」、「権限」プロパティを設定し、「ユーザーを追加」をクリックします。
-
その後、ユーザーの認証トークンが生成されます。各ユーザーの認証トークンとその他の情報は「Users」ページで確認できます。
NetSuite 用のAPI エンドポイントの作成
ユーザーを作成したら、NetSuite のデータ用のAPI エンドポイントを作成していきます。
-
まず、「API」ページに移動し、
「 テーブルを追加」をクリックします。
-
アクセスしたい接続を選択し、次へをクリックします。
-
接続を選択した状態で、各テーブルを選択して確認をクリックすることでエンドポイントを作成します。
OData のエンドポイントを取得
以上でNetSuite への接続を設定してユーザーを作成し、API Server でNetSuite データのAPI を追加しました。これで、OData 形式のNetSuite データをREST API で利用できます。API Server の「API」ページから、API のエンドポイントを表示およびコピーできます。
クロスオリジンリソースシェアリング (CORS)
複数の異なるドメインへのアクセス・接続を行う場合、クロスサイトスクリプティングの制限に抵触する可能性があります。その場合は、「設定」→「サーバー」タブ内の「クロスオリジンリソースシェアリング (CORS)」の設定を行います。
Ignite UI for Angularを組み込んだAngularプロジェクトを準備
IgxGridを利用するためには、Ignite UI for Angularパッケージの組み込みやモジュールの参照が必要になります。下記に必要パッケージを組み込んだ状態のサンプルプロジェクトが公開されています。
GitHub - neri78/IgxGridBasicDemo
リポジトリをクローンしたのち、下記コマンドで現時点の実行結果を確認できます。
npm start
左側のナビゲーションからigxGrid1を選択するとローカルデータがバインドされたIgxGridが表示されます。
APIサーバーからデータを取得するサービスを作成
AngularではAPIサーバーのような外部リソースからデータを取得する場合、サービスを作成しViewとは直接関係のないデータアクセス部分を分離させることが一般的です。 ng generateコマンドを利用し、ApiServerServiceを作成します。
ng generate service service/ApiServer
serviceフォルダーとapi-server.service.spec.ts, api-server.sergice.tsファイルがそれぞれ作成されます。
レスポンスおよび NetSuite のデータのインターフェースを宣言
APIサーバーから NetSuite の情報がvalueに保存されたデータが返されるため、レスポンスおよび、 NetSuite のデータのインターフェースを作成された ApiServerServiceクラスのスコープの外側に宣言します。
api-server.service.ts
// response
interface CustomersResponse {
value: Customer[];
}
// NetSuite Data Excample
export interface Customer {
rowguid: string; // "3f5ae95e-b87d-4aed-95b4-c3797afcb74f"
LastName: string; // "Gee"
PasswordHash: string; // "L/Rlwxzp4w7RWmEgXX+/A7cXaePEPcp+KwQhl2fJL7w="
Suffix: string; // null
Title: string; // "Mr."
EmailAddress: string; // "orlando0@adventure-works.com"
Phone: string; // "245-555-0173"
CustomerID: string; // 1
PasswordSalt: string; // "1KjXYs4="
SalesPerson: string; // "adventure-works\pamela0"
GUID: string; // "3F5AE95EB87D4AED95B4C3797AFCB74F"
CompanyName: string; // "A Bike Store"
FirstName: string; // "Orlando"
NameStyle: boolean; // false
MiddleName: string; // "N."
ModifiedDate: Date; // "2005-08-01T00:00:00.0000+00:00"
}
必要なモジュールをインポート
api-server.service.tsファイルの先頭に戻り、通信、データ処理にに必要なモジュールをそれぞれインポートします。
api-server.service.ts
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map} from 'rxjs/operators';
APIサーバーへの接続に必要なAuthToken、URL、リクエストヘッダを宣言
次に最初に設定したAPIサーバーに接続するためのAuthToken、URL、そして認証に必要なリクエストヘッダをApiServerServiceのプライベート変数として宣言します。
api-server.service.ts
// Auth Token
private authToken = '設定したAuthToken';
// APIサーバーRestAPIのURL、今回は NetSuite のデータを返すRest APIのURLに固定
private baseUrl = ' NetSuite のデータのRest API URL';
// リクエストヘッダ
private headers = new HttpHeaders({
'x-cdata-authtoken': this.authToken
});
コストラクタで依存関係の注入を利用し、HttpClientのインスタンスを取得
コンストラクタの引数として、HttpClientを受け取るように変更します。クラスインスタンスはAngularフレームワークにより作成されます。
api-server.service.ts
constructor(private httpClient: HttpClient) { }
リクエストの設定とレスポンスの処理
NetSuite のデータを取得するgetCustomers()メソッドを宣言し、HttpClient、pipeを利用してリクエストの設定と、レスポンスの処理、エラーハンドリングを実装します。
api-server.service.ts
public getCustomers() {
// HttpClientを利用し、APIサーバーにアクセス
return this.httpClient.get(
`${this.baseUrl}/`, {headers: this.headers})
.pipe(
// エラー時の処理
catchError(this.handleError('getData:Customer', [])),
// 返されたデータからCustomerの配列を取得
map(response => (response as CustomersResponse).value)
);
}
// Error時の処理。デモ用に簡略化
private handleError(operation = 'operation', result?: T) {
return (error: any): string => {
console.error('An error occurred', error);
return error;
};
}
これでサービスの準備が整いました。
グリッド画面でデータを取得
次にグリッドを表示している画面側のコードを実装します。
必要なモジュールをインポート
igxgrid1\igxgrid1.component.tsでは先ほど実装したApiServerServiceと、サービス呼び出しの結果返されるObservableを利用するため、必要なモジュールをインポートします。
igxgrid1\igxgrid1.component.ts
import { ApiServerService, Customer } from '../service/api-server.service';
import { Subscription } from 'rxjs';
購読を管理するためのSubScription変数を宣言
このApiServerServiceはデータを非同期で取得します。そのため、呼び出しが完了した後にロジックを実行するための購読処理を後ほど実装します。この購読は最終的には購読解除を行う必要があるtまえ、プライベート変数を宣言します。
igxgrid1\igxgrid1.component.ts
subscription: Subscription;
コストラクタで依存関係の注入を利用し、ApiServerServiceのインスタンスを取得
igxgrid1\igxgrid1.component.ts
constructor(private apiServerService: ApiServerService) { }
ngOnInitでデータを取得しグリッドにデータを表示
igxgrid1\igxgrid1.component.tsには、ngOnInit()メソッドが実装されており、データグリッド画面の初期化時に、あらかじめ用意されているサンプルデータを読み込むコードが実装されています。このlocalDataにコレクションを代入することでグリッドにデータが表示されます。このコードをコメントアウトします。
igxgrid1\igxgrid1.component.ts
ngOnInit() {
// コメントアウト
// this.localData = employeesData;
}
コメントアウトしたコードの代わりに、ApiServerServiceを利用してデータを取得し、localDataに割り当てるコードを実装します。
igxgrid1\igxgrid1.component.ts
ngOnInit() {
// APIServerを呼び出し、NetSuite のデータを取得
this.subscription = this.apiServerService.getCustomers()
.subscribe( (data: Customer[]) => {
this.localData = data;
});
}
ngOnDestoryで購読を解除
このコンポーネントが破棄されるタイミングでメモリーリークを防ぐため、購読を解除します。
igxgrid1\igxgrid1.component.ts
// unsubscribe
ngOnDestroy() {
if (this.subscription !== undefined) {
this.subscription.unsubscribe();
}
}
サービス、モジュールの登録
最後に作成したサービスや必要なモジュールをアプリケーションに登録します。
モジュール参照のインポート
app.module.tsにApiServerServiceおよびHttpClientModuleをインポートします。
app.module.ts
import { ApiServerService } from './service/api-server.service';
import { HttpClientModule } from '@angular/common/http';
importsセクションでHttpClientModuleをインポート
@NgModuleのimportsセクションにHttpClientModuleをインポートします。
app.module.ts
imports: [
...
,HttpClientModule
],
providersセクションでApiServerServiceを宣言
@NgModuleのimportsセクションにHttpClientModuleをインポートします。
app.module.ts
providers: [ApiServerService],
これで設定は完了です。再度 __npm start__ コマンドで実行してみましょう!

全てのコードはこちらのBranchでご覧いただけます(AuthToken、並びにURLは空白のため適宜設定してください)