# Client Libraries

Gel implements libraries for popular languages that make it easier to work with Gel. These libraries provide a common set of functionality.

- *Instantiating clients.* Most libraries implement a `Client` class that internally manages a pool of physical connections to your Gel instance.

- *Resolving connections.* All client libraries implement a standard protocol for determining how to connect to your database. In most cases, this will involve checking for special environment variables like `GEL_DSN` or, in the case of Gel Cloud instances, `GEL_INSTANCE` and `GEL_SECRET_KEY`. (More on this in [the Connection section below](https://docs.geldata.com/learn/clients.md#ref-intro-clients-connection).)

- *Executing queries.* A `Client` will provide some methods for executing queries against your database. Under the hood, this query is executed using Gel's efficient binary protocol.


> Note: For some use cases, you may not need a client library. Gel allows you to execute [queries over HTTP](https://docs.geldata.com/reference/using/http.md#ref-edgeql-http). This is slower than the binary protocol and lacks support for transactions and rich data types, but may be suitable if a client library isn't available for your language of choice.

## Available libraries

To execute queries from your application code, use one of [Gel's client libraries](https://docs.geldata.com/reference/using/clients.md#ref-clients-index).

## Usage

To follow along with the guide below, first create a new directory and initialize a project.

```bash
$ mydir myproject
$ cd myproject
$ gel project init
```

Configure the environment as needed for your preferred language.

- Node.js:
  ```bash
  $ npm init -y
  $ tsc --init # (TypeScript only)
  $ touch index.ts
  ```
- Deno:
  ```bash
  $ touch index.ts
  ```
- Python:
  ```bash
  $ python -m venv venv
  $ source venv/bin/activate
  $ touch main.py
  ```
- Rust:
  ```bash
  $ cargo init
  ```
- Go:
  ```bash
  $ go mod init example/quickstart
  $ touch hello.go
  ```
- .NET:
  ```bash
  $ dotnet new console -o . -f net6.0
  ```

Install the Gel client library.

- Node.js:
  ```bash
  $ npm install gel    # npm
  $ yarn add gel       # yarn
  ```
- Deno:
  ```txt
  n/a
  ```
- Python:
  ```bash
  $ pip install gel
  ```
- Rust:
  ```toml
  # Cargo.toml
  
  [dependencies]
  gel-tokio = "0.5.0"
  # Additional dependency
  tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread"] }
  ```
- Go:
  ```bash
  $ go get github.com/geldata/gel-go
  ```
- .NET:
  ```bash
  $ dotnet add package Gel.Net.Driver
  ```

Copy and paste the following simple script. This script initializes a `Client` instance. Clients manage an internal pool of connections to your database and provide a set of methods for executing queries.

> Note: Note that we aren't passing connection information (say, a connection URL) when creating a client. The client libraries can detect that they are inside a project directory and connect to the project-linked instance automatically. For details on configuring connections, refer to the [Connection](https://docs.geldata.com/learn/clients.md#ref-intro-clients-connection) section below.

- Node.js:
  ```typescript
  import {createClient} from 'gel';
  
  const client = createClient();
  
  client.querySingle(`select random()`).then((result) => {
    console.log(result);
  });
  ```
- Python:
  ```python
  from gel import create_client
  
  client = create_client()
  
  result = client.query_single("select random()")
  print(result)
  ```
- Rust:
  ```rust
  // src/main.rs
  #[tokio::main]
  async fn main() {
      let conn = gel_tokio::create_client()
          .await
          .expect("Client initiation");
      let val = conn
          .query_required_single::<f64, _>("select random()", &())
          .await
          .expect("Returning value");
      println!("Result: {}", val);
  }
  ```
- Go:
  ```go
  // hello.go
  package main
  
  import (
    "context"
    "fmt"
    "log"
  
    "github.com/geldata/gel-go"
  )
  
  func main() {
    ctx := context.Background()
    client, err := gel.CreateClient(ctx, gel.Options{})
    if err != nil {
      log.Fatal(err)
    }
    defer client.Close()
  
    var result float64
    err = client.
      QuerySingle(ctx, "select random();", &result)
    if err != nil {
      log.Fatal(err)
    }
  
    fmt.Println(result)
  }
  ```
- .NET:
  ```csharp
  using Gel;
  
  var client = new GelClient();
  var result = await client.QuerySingleAsync<double>("select random();");
  Console.WriteLine(result);
  ```
- Elixir:
  ```elixir
  # lib/gel_quickstart.ex
  defmodule GelQuickstart do
    def run do
      {:ok, client} = Gel.start_link()
      result = Gel.query_single!(client, "select random()")
      IO.inspect(result)
    end
  end
  ```

Finally, execute the file.

- Node.js:
  ```bash
  $ npx tsx index.ts
  ```
- Deno:
  ```bash
  $ deno run --allow-all --unstable index.deno.ts
  ```
- Python:
  ```bash
  $ python index.py
  ```
- Rust:
  ```bash
  $ cargo run
  ```
- Go:
  ```bash
  $ go run .
  ```
- .NET:
  ```bash
  $ dotnet run
  ```
- Elixir:
  ```bash
  $ mix run -e GelQuickstart.run
  ```

You should see a random number get printed to the console. This number was generated inside your Gel instance using EdgeQL's built-in [`random()`](https://docs.geldata.com/reference/stdlib/numbers.md#function::std::random) function.

## Connection

All client libraries implement a standard protocol for determining how to connect to your database.

### Using projects

In development, we recommend [initializing a project](https://docs.geldata.com/learn/projects.md#ref-intro-projects) in the root of your codebase.

```bash
$ gel project init
```

Once the project is initialized, any code that uses an official client library will automatically connect to the project-linked instance—no need for environment variables or hard-coded credentials. Follow the [Using projects](https://docs.geldata.com/reference/using/projects.md#ref-guide-using-projects) guide to get started.

### Using environment variables

#### For Gel Cloud

In production, connection information can be securely passed to the client library via environment variables. For Gel Cloud instances, the recommended variables to set are `GEL_INSTANCE` and `GEL_SECRET_KEY`.

Set `GEL_INSTANCE` to `<org-name>/<instance-name>` where `<instance-name>` is the name you set when you created the Gel Cloud instance.

If you have not yet created a secret key, you can do so in the Gel Cloud UI or by running [gel cloud secretkey create](https://docs.geldata.com/reference/using/cli/gel_cloud/gel_cloud_secretkey/edgedb_cloud_secretkey_create.md#ref-cli-gel-cloud-secretkey-create) via the CLI.

#### For self-hosted instances

Most commonly for self-hosted remote instances, you set a value for the `GEL_DSN` environment variable.

> Note: If environment variables like `GEL_DSN` are defined inside a project directory, the environment variables will take precedence.

A DSN is also known as a "connection string" and takes the following form: `gel://<username>:<password>@<hostname>:<port>`.

Each element of the DSN is optional; in fact `gel://` is a technically a valid DSN. Any unspecified element will default to the following values.

|              |             |
| ------------ | ----------- |
| `<host>`     | `localhost` |
| `<port>`     | `5656`      |
| `<user>`     | admin       |
| `<password>` | `null`      |

A typical DSN may look like this: `gel://admin:PASSWORD@db.domain.com:8080`.

DSNs can also contain the following query parameters.

|                |                                                                                                                                                                                                                            |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `branch`       | The database branch to connect to within the given instance. Defaults to main.                                                                                                                                             |
| `tls_security` | The TLS security mode. Accepts the following values.

- `"strict"` (**default**) — verify certificates and hostnames
- `"no_host_verification"` — verify certificates only
- `"insecure"` — trust self-signed certificates |
| `tls_ca_file`  | A filesystem path pointing to a CA root certificate. This is usually only necessary when attempting to connect via TLS to a remote instance with a self-signed certificate.                                                |

These parameters can be added to any DSN using web-standard query string notation: `gel://user:pass@example.com:8080?branch=my_branch&tls_security=insecure`.

For a more comprehensive guide to DSNs, see the [DSN Specification](https://docs.geldata.com/reference/using/connection.md#ref-dsn).

#### Using multiple environment variables

If needed for your deployment pipeline, each element of the DSN can be specified independently.

- `GEL_HOST`
- `GEL_PORT`
- `GEL_USER`
- `GEL_PASSWORD`
- `GEL_BRANCH`
- `GEL_TLS_CA_FILE`
- `GEL_CLIENT_TLS_SECURITY`

> Note: If a value for `GEL_DSN` is defined, it will override these variables!

### Other mechanisms

`GEL_CREDENTIALS_FILE`:
A path to a `.json` file containing connection information. In some scenarios (including local Docker development) its useful to represent connection information with files.

```json
{
  "host": "localhost",
  "port": 10700,
  "user": "testuser",
  "password": "testpassword",
  "branch": "main",
  "tls_cert_data": "-----BEGIN CERTIFICATE-----\nabcdef..."
}
```



`GEL_INSTANCE` (local/Gel Cloud only):
The name of an instance. Useful only for local or Gel Cloud instances.

> Note: For more on Gel Cloud instances, see the [Gel Cloud instance connection section](https://docs.geldata.com/learn/clients.md#ref-intro-clients-connection-cloud) above.



### Reference

These are the most common ways to connect to an instance, however Gel supports several other options for advanced use cases. For a complete reference on connection configuration, see [Reference > Connection Parameters](https://docs.geldata.com/reference/using/connection.md#ref-reference-connection).

