[[connecting]]
== Connecting

This page contains the information you need to connect and use the Client with 
{es}.

**On this page**

* <<auth-reference, Authentication options>>
* <<client-usage, Using the client>>

[discrete]
[[auth-reference]]
=== Authentication

This document contains code snippets to show you how to connect to various {es} 
providers.


[discrete]
[[auth-basic]]
==== Basic authentication

To set the cluster endpoints, the username, and the password programatically, pass a configuration object to the `elasticsearch.NewClient()` function.

[source,go]
------------------------------------
cfg := elasticsearch.Config{
  Addresses: []string{
    "http://localhost:9200",
    "http://localhost:9201",
  },
  Username: "foo",
  Password: "bar",
}
es, err := elasticsearch.NewClient(cfg)
------------------------------------

You can also include the username and password in the endpoint URL:

```
'https://username:password@localhost:9200'
```


[discrete]
[[auth-ec]]
==== Elastic Cloud

If you are using https://www.elastic.co/cloud[Elastic Cloud], the client offers 
an easy way to connect to it. You must pass the Cloud ID that you can find in 
the cloud console and the corresponding API key.

[source,go]
------------------------------------
cfg := elasticsearch.Config{
		CloudID: "CLOUD_ID",
		APIKey: "API_KEY"
}
es, err := elasticsearch.NewClient(cfg)
------------------------------------

[discrete]
[[compatibility-mode]]
=== Compatibility mode

The {es} server version 8.0 is introducing a new compatibility mode that allows you a smoother upgrade experience from 7 to 8. In a nutshell, you can use the latest 7.x `go-elasticsearch` Elasticsearch client with an 8.x Elasticsearch server, giving more room to coordinate the upgrade of your codebase to the next major version.

If you want to leverage this functionality, please make sure that you are using the latest 7.x `go-elasticsearch` client and set the environment variable `ELASTIC_CLIENT_APIVERSIONING` to `true` or the configuration option `config.EnableCompatibilityMode` in the client `Config`. The client is handling the rest internally. For every 8.0 and beyond `go-elasticsearch` client, you're all set! The compatibility mode is enabled by default.

[discrete]
[[client-usage]]
=== Using the client

The {es} package ties together two separate packages for calling the Elasticsearch APIs and transferring data over HTTP: `esapi` and `estransport`, respectively.

Use the `elasticsearch.NewDefaultClient()` function to create the client with the default settings.

[source,go]
------------------------------------
es, err := elasticsearch.NewDefaultClient()
if err != nil {
  log.Fatalf("Error creating the client: %s", err)
}

res, err := es.Info()
if err != nil {
  log.Fatalf("Error getting response: %s", err)
}

defer res.Body.Close()
log.Println(res)
------------------------------------

[discrete]
[[connecting-faas]]
=== Using the Client in a Function-as-a-Service Environment

This section illustrates the best practices for leveraging the {es} client in a Function-as-a-Service (FaaS) environment.
The most influential optimization is to initialize the client outside of the function, the global scope.
This practice does not only improve performance but also enables background functionality as – for example –
https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[sniffing].
The following examples provide a skeleton for the best practices.

[discrete]
[[connecting-faas-gcp]]
==== GCP Cloud Functions

[source,go]
----------------------------
package httpexample

import (
	"github.com/elastic/go-elasticsearch/v7"
)

var client *elasticsearch.Client

func init() {
	var err error

	... # Client configuration
	client, err = elasticsearch.NewClient(cfg)
	if err != nil {
		log.Fatalf("elasticsearch.NewClient: %v", err)
	}
}

func HttpExample(w http.ResponseWriter, r *http.Request) {
	... # Client usage
}

----------------------------

[discrete]
[[connecting-faas-aws]]
==== AWS Lambda

[source,go]
----------------------------
package httpexample

import (
	"github.com/aws/aws-lambda-go/lambda"
	"github.com/elastic/go-elasticsearch/v7"
)

var client *elasticsearch.Client

func init() {
	var err error

	... # Client configuration
	client, err = elasticsearch.NewClient(cfg)
	if err != nil {
		log.Fatalf("elasticsearch.NewClient: %v", err)
	}
}

func HttpExample() {
	... # Client usage
}

func main() {
	lambda.Start(HttpExample)
}
----------------------------

Resources used to assess these recommendations:

* https://cloud.google.com/functions/docs/bestpractices/tips#use_global_variables_to_reuse_objects_in_future_invocations[GCP Cloud Functions: Tips & Tricks]
* https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html[Best practices for working with AWS Lambda functions]
* https://docs.aws.amazon.com/lambda/latest/operatorguide/global-scope.html[AWS Lambda: Comparing the effect of global scope]
