All Products
Search
Document Center

OpenSearch:Contoh konstruktor permintaan TypeScript

Last Updated:Apr 01, 2026

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:

PackageTujuan
@alicloud/credentialsMengelola kredensial Alibaba Cloud, termasuk refresh AccessKey dan token STS
@alicloud/opensearch-utilMenghasilkan signature permintaan dan menghitung Content-MD5 untuk permintaan OpenSearch
@alicloud/tea-typescriptRuntime HTTP inti: menangani eksekusi permintaan, retry, dan backoff
@alicloud/tea-utilFungsi utilitas untuk serialisasi, pembuatan header, dan penguraian respons

devDependencies — diperlukan untuk kompilasi TypeScript:

PackageTujuan
typescriptKompilator TypeScript
ts-nodeMenjalankan 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:

  1. Mengambil kredensial dari penyedia kredensial yang dikonfigurasi

  2. Menetapkan header yang diperlukan (Date, X-Opensearch-Nonce, Authorization, dan opsional X-Opensearch-Security-Token)

  3. Menghitung Content-MD5 untuk badan permintaan

  4. Menjalankan permintaan dengan perilaku retry dan backoff yang dapat dikonfigurasi

  5. 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;
Penting

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.ts untuk mendefinisikan antarmuka konfigurasi yang diharapkan oleh Client

  • Gunakan Client._request() untuk memanggil API OpenSearch dengan meneruskan metode HTTP, path, parameter kueri, dan badan permintaan