Demo code for the Go client

更新时间:
复制 MD 格式

This page provides the Go client source code for Alibaba Cloud OpenSearch Industry Algorithm Edition. The client handles authentication, request signing, and HTTP communication with the OpenSearch API. For higher-level operations such as querying and indexing, use this client as the foundation for building your own request logic.

Prerequisites

Before you begin, ensure that you have:

  • Go installed

  • An Alibaba Cloud account with OpenSearch Industry Algorithm Edition enabled

  • An AccessKey ID and AccessKey Secret

Install dependencies

Run the following commands to add the required packages to your Go module:

go get github.com/alibabacloud-go/opensearch-util/service
go get github.com/alibabacloud-go/tea-utils/service
go get github.com/alibabacloud-go/tea/tea
go get github.com/aliyun/credentials-go/credentials

Client source code

The following code defines the Config and Client structs, initializes credentials, and sends signed HTTP requests to the OpenSearch API.

Store your AccessKey ID and AccessKey Secret in environment variables rather than hardcoding them in source code.
// This file is auto-generated, don't edit it. Thanks.
/**
 *
 */
package client

import (
    opensearchutil "github.com/alibabacloud-go/opensearch-util/service"
    util "github.com/alibabacloud-go/tea-utils/service"
    "github.com/alibabacloud-go/tea/tea"
    credential "github.com/aliyun/credentials-go/credentials"
)

type Config struct {
    Endpoint        *string `json:"endpoint,omitempty" xml:"endpoint,omitempty"`
    Protocol        *string `json:"protocol,omitempty" xml:"protocol,omitempty"`
    Type            *string `json:"type,omitempty" xml:"type,omitempty"`
    SecurityToken   *string `json:"securityToken,omitempty" xml:"securityToken,omitempty"`
    AccessKeyId     *string `json:"accessKeyId,omitempty" xml:"accessKeyId,omitempty"`
    AccessKeySecret *string `json:"accessKeySecret,omitempty" xml:"accessKeySecret,omitempty"`
    UserAgent       *string `json:"userAgent,omitempty" xml:"userAgent,omitempty"`
}

func (s Config) String() string {
    return tea.Prettify(s)
}

func (s Config) GoString() string {
    return s.String()
}

func (s *Config) SetEndpoint(v string) *Config {
    s.Endpoint = &v
    return s
}

func (s *Config) SetProtocol(v string) *Config {
    s.Protocol = &v
    return s
}

func (s *Config) SetType(v string) *Config {
    s.Type = &v
    return s
}

func (s *Config) SetSecurityToken(v string) *Config {
    s.SecurityToken = &v
    return s
}

func (s *Config) SetAccessKeyId(v string) *Config {
    s.AccessKeyId = &v
    return s
}

func (s *Config) SetAccessKeySecret(v string) *Config {
    s.AccessKeySecret = &v
    return s
}

func (s *Config) SetUserAgent(v string) *Config {
    s.UserAgent = &v
    return s
}

type Client struct {
    Endpoint   *string
    Protocol   *string
    UserAgent  *string
    Credential credential.Credential
}

func NewClient(config *Config) (*Client, error) {
    client := new(Client)
    err := client.Init(config)
    return client, err
}

func (client *Client) Init(config *Config) (_err error) {
    if tea.BoolValue(util.IsUnset(tea.ToMap(config))) {
        _err = tea.NewSDKError(map[string]interface{}{
            "name":    "ParameterMissing",
            "message": "'config' can not be unset",
        })
        return _err
    }

    if tea.BoolValue(util.Empty(config.Type)) {
        config.Type = tea.String("access_key")
    }

    credentialConfig := &credential.Config{
        AccessKeyId:     config.AccessKeyId,
        Type:            config.Type,
        AccessKeySecret: config.AccessKeySecret,
        SecurityToken:   config.SecurityToken,
    }
    client.Credential, _err = credential.NewCredential(credentialConfig)
    if _err != nil {
        return _err
    }

    client.Endpoint = config.Endpoint
    client.Protocol = config.Protocol
    client.UserAgent = config.UserAgent
    return nil
}

func (client *Client) Request(method *string, pathname *string, query map[string]interface{}, headers map[string]*string, body interface{}, runtime *util.RuntimeOptions) (_result map[string]interface{}, _err error) {
    _err = tea.Validate(runtime)
    if _err != nil {
        return _result, _err
    }
    _runtime := map[string]interface{}{
        "timeouted":      "retry",
        "readTimeout":    tea.IntValue(runtime.ReadTimeout),
        "connectTimeout": tea.IntValue(runtime.ConnectTimeout),
        "httpProxy":      tea.StringValue(runtime.HttpProxy),
        "httpsProxy":     tea.StringValue(runtime.HttpsProxy),
        "noProxy":        tea.StringValue(runtime.NoProxy),
        "maxIdleConns":   tea.IntValue(runtime.MaxIdleConns),
        "retry": map[string]interface{}{
            "retryable":   tea.BoolValue(runtime.Autoretry),
            "maxAttempts": tea.IntValue(util.DefaultNumber(runtime.MaxAttempts, tea.Int(3))),
        },
        "backoff": map[string]interface{}{
            "policy": tea.StringValue(util.DefaultString(runtime.BackoffPolicy, tea.String("no"))),
            "period": tea.IntValue(util.DefaultNumber(runtime.BackoffPeriod, tea.Int(1))),
        },
        "ignoreSSL": tea.BoolValue(runtime.IgnoreSSL),
    }

    _resp := make(map[string]interface{})
    for _retryTimes := 0; tea.BoolValue(tea.AllowRetry(_runtime["retry"], tea.Int(_retryTimes))); _retryTimes++ {
        if _retryTimes > 0 {
            _backoffTime := tea.GetBackoffTime(_runtime["backoff"], tea.Int(_retryTimes))
            if tea.IntValue(_backoffTime) > 0 {
                tea.Sleep(_backoffTime)
            }
        }

        _resp, _err = func() (map[string]interface{}, error) {
            request_ := tea.NewRequest()
            accesskeyId, _err := client.GetAccessKeyId()
            if _err != nil {
                return _result, _err
            }

            accessKeySecret, _err := client.GetAccessKeySecret()
            if _err != nil {
                return _result, _err
            }

            request_.Protocol = util.DefaultString(client.Protocol, tea.String("HTTP"))
            request_.Method = method
            request_.Pathname = pathname
            request_.Headers = tea.Merge(map[string]*string{
                "user-agent":         client.GetUserAgent(),
                "Date":               opensearchutil.GetDate(),
                "host":               util.DefaultString(client.Endpoint, tea.String("opensearch-cn-hangzhou.aliyuncs.com")),
                "X-Opensearch-Nonce": util.GetNonce(),
            }, headers)
            if !tea.BoolValue(util.IsUnset(query)) {
                request_.Query = util.StringifyMapValue(query)
            }

            if !tea.BoolValue(util.IsUnset(body)) {
                reqBody := util.ToJSONString(body)
                request_.Headers["Content-MD5"] = opensearchutil.GetContentMD5(reqBody)
                request_.Headers["Content-Type"] = tea.String("application/json")
                request_.Body = tea.ToReader(reqBody)
            }

            request_.Headers["Authorization"] = opensearchutil.GetSignature(request_, accesskeyId, accessKeySecret)
            response_, _err := tea.DoRequest(request_, _runtime)
            if _err != nil {
                return _result, _err
            }
            objStr, _err := util.ReadAsString(response_.Body)
            if _err != nil {
                return _result, _err
            }

            if tea.BoolValue(util.Is4xx(response_.StatusCode)) || tea.BoolValue(util.Is5xx(response_.StatusCode)) {
                _err = tea.NewSDKError(map[string]interface{}{
                    "message": tea.StringValue(response_.StatusMessage),
                    "data":    tea.StringValue(objStr),
                    "code":    tea.IntValue(response_.StatusCode),
                })
                return _result, _err
            }

            obj := util.ParseJSON(objStr)
            res := util.AssertAsMap(obj)
            _result = make(map[string]interface{})
            _err = tea.Convert(map[string]interface{}{
                "body":    res,
                "headers": response_.Headers,
            }, &_result)
            return _result, _err
        }()
        if !tea.BoolValue(tea.Retryable(_err)) {
            break
        }
    }

    return _resp, _err
}

func (client *Client) SetUserAgent(userAgent *string) {
    client.UserAgent = userAgent
}

func (client *Client) AppendUserAgent(userAgent *string) {
    client.UserAgent = tea.String(tea.StringValue(client.UserAgent) + " " + tea.StringValue(userAgent))
}

func (client *Client) GetUserAgent() (_result *string) {
    userAgent := util.GetUserAgent(client.UserAgent)
    _result = userAgent
    return _result
}

func (client *Client) GetAccessKeyId() (_result *string, _err error) {
   if tea.BoolValue(util.IsUnset(client.Credential)) {
       return _result, _err
   }

   accessKeyId, _err := client.Credential.GetAccessKeyId()
   if _err != nil {
       return _result, _err
   }

   _result = accessKeyId
   return _result, _err
}

func (client *Client) GetAccessKeySecret() (_result *string, _err error) {
   if tea.BoolValue(util.IsUnset(client.Credential)) {
       return _result, _err
   }

   secret, _err := client.Credential.GetAccessKeySecret()
   if _err != nil {
       return _result, _err
   }

   _result = secret
   return _result, _err
}

Key concepts

Config fields

FieldTypeDescriptionDefault
Endpoint*stringThe OpenSearch service endpointopensearch-cn-hangzhou.aliyuncs.com
Protocol*stringThe request protocolHTTP
Type*stringThe credential typeaccess_key
AccessKeyId*stringYour AccessKey ID
AccessKeySecret*stringYour AccessKey Secret
SecurityToken*stringThe security token for Security Token Service (STS) temporary credentials
UserAgent*stringA custom user agent string

Request behavior

The Request method sets the following headers on every call: user-agent, Date, host, X-Opensearch-Nonce, and Authorization. When a request body is present, it also sets Content-MD5 and Content-Type: application/json. The client signs each request using your AccessKey credentials.

Retry and error handling

The client makes up to 3 total attempts by default (1 initial attempt plus up to 2 retries) with no backoff. HTTP 4xx and 5xx responses are treated as errors. Pass a RuntimeOptions value to Request to configure read timeout, connect timeout, HTTP proxy, HTTPS proxy, max idle connections, retry behavior, and SSL verification.

Next steps