問題
UI5アプリケーションからリモートAPIを呼び出すとき、以下のように書きたくなります。
const url = '/http/get_csv';
const response = await fetch(url, {
method: "GET",
headers: {
"Accept": "text/csv"
}
});
BTPで実行すると、このリクエストは404エラーになってしまいます(以下はHTML5 Application Repositoryから実行した場合)。
正常に実行できている他のリクエストでは、URLに<destinationのサービスインスタンスID>.<アプリケーションのネームスペース+ID>.<アプリケーションのネームスペース+ID>-<バージョン>
が追加されています。
試しにこの先頭部分をコピーしてブラウザに貼り、末尾に目的のパスをつけると、正常にリクエストが実行できます。
どうすればよいか
URLの先頭にベースパスを追加します。
const cpiUrl = this.getBaseURL() + '/http/get_csv'
const response = await fetch(cpiUrl, {
method: "GET",
headers: {
"Accept": "text/csv"
}
});
ベースパスを返すメソッドの実装は以下です。何やら複雑ですが、BTPで実行するとこのメソッドからは.
が、ローカル実行の場合は..
が返ってきます。
private getBaseURL(): string {
const component = this.getOwnerComponent();
const appId = component?.getManifestEntry("/sap.app/id");
const appPath = appId.replace(/\./g, "/");
return sap.ui.require.toUrl(appPath);
}
余談ですが、昔はjQueryを使用していました。jQueryが非推奨になったため、sap.ui.require.toUrlを使うようになりました。
getBaseURL: function () {
var appId = this.getOwnerComponent().getManifestEntry("/sap.app/id");
var appPath = appId.replaceAll(".", "/");
var appModulePath = jQuery.sap.getModulePath(appPath);
return appModulePath;
}
BTPで実行するための設定
BTPから実行するためには、xs-app.json
でルートの設定が必要です。Destinationは事前に登録しておきます。
{
"welcomeFile": "/index.html",
"authenticationMethod": "route",
"routes": [
{
"source": "^/http/(.*)$",
"target": "/http/$1",
"destination": "cloud-integration",
"authenticationType": "xsuaa",
"csrfProtection": false
},
...
]
}
ローカル(BAS)で実行するための設定
ui5-yamlに以下の設定を追加します。fiori-tools-proxyが特定のパスを指定したdestinationに転送してくれます。
server:
customMiddleware:
- name: fiori-tools-proxy
afterMiddleware: compression
configuration:
ignoreCertErrors: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted
ui5:
path:
- /resources
- /test-resources
url: https://ui5.sap.com
# 追加
backend:
- path: /http
destination: cloud-integration