Client.ts menyediakan klien HTTP yang dapat digunakan kembali untuk OpenSearch Industry Algorithm Edition. Klien ini menangani penandatanganan permintaan, manajemen kredensial, logika pengulangan (retry), dan penanganan error sehingga Anda dapat fokus membangun fitur pencarian.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Node.js dan npm yang telah diinstal
Akun Alibaba Cloud dengan ID AccessKey dan AccessKey Secret
Titik akhir layanan OpenSearch Industry Algorithm Edition untuk instans Anda
Instal dependensi
Tambahkan paket berikut ke package.json Anda. Instal dari npm.
dependencies — diperlukan saat runtime:
| Package | Tujuan |
|---|---|
@alicloud/credentials | Mengelola kredensial Alibaba Cloud, termasuk refresh AccessKey dan token STS |
@alicloud/opensearch-util | Menghasilkan signature permintaan dan menghitung Content-MD5 untuk permintaan OpenSearch |
@alicloud/tea-typescript | Runtime HTTP inti: menangani eksekusi permintaan, retry, dan backoff |
@alicloud/tea-util | Fungsi utilitas untuk serialisasi, pembuatan header, dan penguraian respons |
devDependencies — diperlukan untuk kompilasi TypeScript:
| Package | Tujuan |
|---|---|
typescript | Kompilator TypeScript |
ts-node | Menjalankan file TypeScript secara langsung tanpa langkah kompilasi terpisah |
Client.ts
Client.ts membuat dan mengirim permintaan HTTP yang ditandatangani ke OpenSearch. Semua permintaan melewati metode _request, yang:
Mengambil kredensial dari penyedia kredensial yang dikonfigurasi
Menetapkan header yang diperlukan (
Date,X-Opensearch-Nonce,Authorization, dan opsionalX-Opensearch-Security-Token)Menghitung
Content-MD5untuk badan permintaanMenjalankan permintaan dengan perilaku retry dan backoff yang dapat dikonfigurasi
Mengembalikan badan respons dan header yang telah diurai, atau melempar error pada kode status 4xx/5xx
import OpenSearchUtil from '@alicloud/opensearch-util/dist/client';
import * as $tea from '@alicloud/tea-typescript';
import Util, * as $Util from '@alicloud/tea-util';
import Credential, * as $Credential from '@alicloud/credentials';
import Config from "./Config";
class Client {
_endpoint: string;
_protocol: string;
_userAgent: string;
_credential: Credential;
constructor(config: Config) {
if (Util.isUnset($tea.toMap(config))) {
throw $tea.newError({
name: "ParameterMissing",
message: "'config' can not be unset",
});
}
if (Util.empty(config.type)) {
config.type = "access_key";
}
let credentialConfig = new $Credential.Config({
accessKeyId: config.accessKeyId, // AccessKey ID — muat dari variabel lingkungan, jangan hardcode
type: config.type,
accessKeySecret: config.accessKeySecret, // AccessKey Secret — muat dari variabel lingkungan, jangan hardcode
securityToken: config.securityToken, // Token keamanan STS (hanya diperlukan untuk kredensial temporary)
});
this._credential = new Credential(credentialConfig);
this._endpoint = config.endpoint;
this._protocol = config.protocol;
this._userAgent = config.userAgent;
}
async _request(method: string, pathname: string, query: {[key: string ]: any}, headers: {[key: string ]: string}, body: any, runtime: $Util.RuntimeOptions): Promise<{[key: string ]: any}> {
let _runtime: { [key: string]: any } = {
timeouted: "retry",
readTimeout: runtime.readTimeout,
connectTimeout: runtime.connectTimeout,
httpProxy: runtime.httpProxy,
httpsProxy: runtime.httpsProxy,
noProxy: runtime.noProxy,
maxIdleConns: runtime.maxIdleConns,
retry: {
retryable: runtime.autoretry,
maxAttempts: Util.defaultNumber(runtime.maxAttempts, 3), // default: 3 kali percobaan
},
backoff: {
policy: Util.defaultString(runtime.backoffPolicy, "no"), // default: tanpa backoff
period: Util.defaultNumber(runtime.backoffPeriod, 1),
},
ignoreSSL: runtime.ignoreSSL,
}
let _lastRequest = null;
let _now = Date.now();
let _retryTimes = 0;
while ($tea.allowRetry(_runtime['retry'], _retryTimes, _now)) {
if (_retryTimes > 0) {
let _backoffTime = $tea.getBackoffTime(_runtime['backoff'], _retryTimes);
if (_backoffTime > 0) {
await $tea.sleep(_backoffTime);
}
}
_retryTimes = _retryTimes + 1;
try {
let request_ = new $tea.Request();
let accesskeyId = await this._credential.getAccessKeyId();
let accessKeySecret = await this._credential.getAccessKeySecret();
let securityToken = await this._credential.getSecurityToken();
request_.protocol = Util.defaultString(this._protocol, "HTTP");
request_.method = method;
request_.pathname = pathname;
request_.headers = {
'user-agent': Util.getUserAgent(this._userAgent),
Date: OpenSearchUtil.getDate(),
'Content-Type':'application/json',
host: Util.defaultString(this._endpoint, `opensearch-cn-hangzhou.aliyuncs.com`),
'X-Opensearch-Nonce': Util.getNonce(), // Nonce unik per permintaan untuk mencegah serangan replay
...headers,
};
if (!Util.isUnset(query)) {
request_.query = Util.stringifyMapValue(query);
}
if (!Util.isUnset(securityToken) && securityToken!='') {
request_.headers["X-Opensearch-Security-Token"] = securityToken; // Diperlukan untuk kredensial temporary STS
}
if (!Util.isUnset(body)) {
let reqBody = Util.toJSONString(body);
request_.headers["Content-Type"] = "application/json";
request_.headers["Content-MD5"] = OpenSearchUtil.getContentMD5(reqBody); // Pemeriksaan integritas untuk badan permintaan
request_.body = new $tea.BytesReadable(reqBody);
}
request_.headers["Authorization"] = OpenSearchUtil.getSignature(request_, accesskeyId, accessKeySecret); // Signature HMAC untuk otentikasi
_lastRequest = request_;
let response_ = await $tea.doAction(request_, _runtime);
let objStr = await Util.readAsString(response_.body);
let obj = Util.parseJSON(objStr);
let res = Util.assertAsMap(obj);
if (Util.is4xx(response_.statusCode) || Util.is5xx(response_.statusCode)) {
throw $tea.newError({
message: response_.statusMessage,
data: objStr,
code: response_.statusCode,
});
}
return {
body: res,
headers: response_.headers,
};
} catch (ex) {
if ($tea.isRetryable(ex)) {
continue;
}
throw ex;
}
}
throw $tea.newUnretryableError(_lastRequest);
}
}
export default Client;Jangan pernah hardcode accessKeyId atau accessKeySecret di kode sumber Anda. Muat kredensial dari variabel lingkungan atau secrets manager untuk menghindari eksposur yang tidak disengaja.
Langkah selanjutnya
Implementasikan
Config.tsuntuk mendefinisikan antarmuka konfigurasi yang diharapkan olehClientGunakan
Client._request()untuk memanggil API OpenSearch dengan meneruskan metode HTTP, path, parameter kueri, dan badan permintaan