Managing backend connections

Configure your API keys and database connections in API Connect for GraphQL.

To access the data in your backends with API Connect for GraphQL, you must specify authentication and connection properties such as user names, passwords, DSN, and authorizations in the config.yaml file.

What is the config.yaml file?

You specify authentication and connection information by passing it to the appropriate connector (@rest, @dbquery, or @graphql directive. The information is managed in a single file named config.yaml.

The config.yaml file must be placed in the root of your project, at the same level as your index.graphql file:

my-stepzen-folder
    .
    ├── index.graphql
    ├── config.yaml
    └── schemas

The config.yaml file is written in YAML to relay information regarding your configuration and keys to API Connect Essentials. While a config.yaml is not always required for a schema to work, you'll generally need this file when using a REST service or a database.

What you specify in your config.yaml might differ depending on the connection type, but there are a few lines you will always need:

configurationset:
  - configuration:
      name: api_config
  - configuration: 
      name: database_config
  • configurationset: Parent that contains the full set of configurations.
  • configuration: Defines a new configuration.
  • name: Name of your configuration; this can be anything you choose.

REST configurations

If a REST service is public and you do not need an API key, you might not need a configuration. However, you can still use configurations to pass any values into @rest. For example, the following configuration contains a username key:

configurationset:
  - configuration:
      name: dev_config
      username: remotesynth

This configuration value can be used when constructing the endpoint URL, as in the following query:

type Query {
  myArticles: [Article]
    @rest(
      endpoint: "https://dev.to/api/articles?username=$username"
      configuration: "dev_config"
    )
}
In this case, the value of $username will be replaced with the value of username from dev_config (for example, remotesynth).
Pass an API key with the Authorization header
If a REST service requires an API key that is passed using the Authorization header, pass it with the Authorization key of the configuration:
configurationset:
  - configuration:
      name: github_config
      Authorization: Bearer MY_PERSONAL_ACCESS_TOKEN
Pass additional header values
Some APIs require that you pass API keys or other values in the header with named keys other than the Authorization header. Pass these in the header by prefixing header. to the key name:
configurationset:
  - configuration:
      name: dev_config
      header.api-key: MY_API_KEY

MySQL configuration

For MySQL databases, you must pass the DSN that contains the connection information for that MySQL database:

- configuration:
    name: mysql_config
    dsn: username:password@tcp(a.b.c.d:port)/dbname

The dsn value can include the parameters listed in Table 1:

Table 1. Parameters for the dsn value in a MySQL configuration
dsn Value Description Example
username Your username john
password Your MySQL database password secretpassword
a.b.c.d:port Your host and port specification tcp(us.address.from.deployment.service:8090)
dbname Your MySQL database name mydbname
tls (optional) Enables TLS / SSL encrypted connection to the server tls=true

The following example shows the dsn portion:

dsn: john:secretpassword@tcp(us.address.from.deployment.service:8090)/mydbname

If your database requires a TLS / SSL encrypted connection, add tls=true to your dsn string:

dsn: john:secretpassword@tcp(us.address.from.deployment.service:8090)/mydbname?tls=true

PostgreSQL configuration

For a PostgreSQL database connection, you must provide a configuration with a URI in a format like the following:

configurationset:
  - configuration:
      name: postgresql_config
      uri: postgresql://username:password@address:port/dbname

The uri value can include the parameters shown in Table 2:

Table 2. Parameters for the uri value in a PostgreSQL configuration
uri Value Description Example
postgresql:// You can leave the postgresql://part of the uri as it is
username Username is username lucy
password Password in password mysecretpassword
address Address in address address.from.deployment.service
port Port is port. Optional if not default 5432
dbname Database name in dbname mydbname
sslmode (optional) Enables TLS / SSL encrypted connection to the server sslmode=true

The following shows a full example for the dsn portion:

uri: 'postgresql://lucy:mysecretpassword@address.from.deployment.service/mydbname'

If your database requires a TLS / SSL encrypted connection, add sslmode=true to your uri string:

uri: 'postgresql://lucy:mysecretpassword@address.from.deployment.service/mydbname?sslmode=true'

PostgreSQL requires passwords containing special characters (such as #$%&) to be URL-encoded. For example, if your password is pa$$word, it needs to be encoded as pa%24%24word. Quotation marks around the uri are required when it is URL-encoded. You can use the urlencoder.org tool to encode your password.

Oracle configuration

For an Oracle database connection, you must provide a configuration with a URL in a format like the following:

configurationset:
  - configuration:
      name: oracle_config
      url: jdbc:oracle:thin:[<user>/<password>]@//<host>[:<port>]/<service>

The url value can include the parameters shown in Table 3:

Table 3. Parameters for the uri value in a Db2 configuration
URL Value Description Example
jdbc:oracle:thin Specifies the Oracle JDBC Thin driver
user Oracle database username scott
password Password for the specified user mysecretpassword
host Host name or IP address of the Oracle server 192.0.2.146
port Host port, the default port is 1521 1521
service The Oracle service name or the database instance you want to connect to myservicename

The following shows a full example for the dsn portion:

jdbc:oracle:thin:lucy/password@//sz-oracle-host:1521/myservicename

Db2 configuration

For a Db2 database connection, you must provide a configuration with a URL in a format like the following:

configurationset:
  - configuration:
      name: db2_config
      url: jdbc:db2://<host>:<port>/<database>:user=<user>;password=<password>;sslConnection=<true/false>;
currentSchema=<schema>

The url value can include the parameters shown in Table 4:

Table 4. Parameters for the uri value in a Db2 configuration
URL Value Description Example
jdbc:db2:// You can leave the jdbc:db2://part of the URL as it is
host Host name or IP address 192.0.2.146
port Host port, the default port is 1433 1433
database Your Db2 database name. mydbname
user User is username lucy
password Password in password mysecretpassword
sslConnection (optional) Enables TLS / SSL encrypted connection to the server sslConnection=true
currentSchema Your Db2 schema name myschemaname

The following shows a full example for the dsn portion:

jdbc:db2://192.0.2.146:1433/mydb2name:user=lucy;password=mysecretpassword;sslConnection=true;
currentSchema=myschemaname

MSSQL configuration

For MSSQL databases, you must pass the DSN that contains the connection information for that MSSQL database:

configurationset:
  - configuration:
      name: mssql_config
      dsn: "sqlserver://username:password@host:port?database=dbname"

The dsn value can include the parameters listed in Table 5:

Table 5. Parameters for the dsn value in a MSSQL configuration
dsn Value Description Example
sqlserver:// You can leave the sqlserver://part of the URI as-is
username Your username lucy
password Your password mysecretpassword
host Host name or IP address 192.0.2.146
port Host port, the default port is 1433 1433
database Your MSSQL database name. database=mydbname
encrypt (optional) Enables TLS / SSL encrypted connection to the server encrypt=true

The following shows an example for the dsn portion:

dsn: sqlserver://lucy:mysecretpassword@192.0.2.146:1433?database=mydbname

If your database requires TLS/SSL encrypted connection, add encrypt=true to your dns string:

dsn: sqlserver://lucy:mysecretpassword@192.0.2.146:1433?database=mydbname&encrypt=true

Snowflake configuration

For Snowflake databases, you must pass the DSN that contains the connection information for that Snowflake database:

configurationset:
  - configuration:
      name: snowflake_config
      dsn: "username:password@account_identifier/database/schemaname?warehouse=warehousename"

The dsn value can include the parameters listed in Table 6:

Table 6. Parameters for the dsn value in a Snowflake configuration
dsn Value Description Example
username Your username lucy
password Your password mysecretpassword
account_identifier Your account identifier ac123456.us-central1.gcp
database Your Snowflake database name mydbname
schemaname Your Snowflake schema name myschemaname
warehousename Your Snowflake warehouse name warehouse=mydbname_wh

The account identifier depends upon your Snowflake account edition. For information, see the Snowflake documentation.

The following shows an example for the dsn portion:

dsn: "lucy:mysecretpassword@ac123456.us-centra1.gcp/mydbname/myschemaname?warehouse=mydbname_wh"

Presto configuration

For Presto databases, you must pass the DSN that contains the connection information for that Presto database:

configurationset:
  - configuration:
      name: presto_config
      dsn: "protocol://username:password@account_identifier[:port]/catalog/schema"

The dsn value can include the parameters listed in Table 7:

Table 7. Parameters for the dsn value in a Presto configuration
dsn Value Description Example
protocol Communication method used to connect to the Presto database presto
username Your username lucy
password Your password mysecretpassword
account_identifier Your account identifier ac123456.us-central1.gcp
port Your port number 8080
catalog Top-level namespace that groups schemas hive
schema Your Presto schema name myschemaname

The account identifier depends upon your Presto account edition. For information, see the Presto documentation.

The following shows an example for the dsn portion:

dsn: "lucy:mysecretpassword@ac123456.us-centra1.gcp:8080/hive/myschemaname"

Trino configuration

For Trino databases, you must pass the DSN that contains the connection information for that Trino database:

configurationset:
  - configuration:
      name: trino_config
      dsn: "protocol://username@hostname[:port]?catalog=<catalog_name>&schema=<schema_name>"

The dsn value can include the parameters listed in Table 8:

Table 8. Parameters for the dsn value in a Trino configuration
dsn Value Description Example
protocol Protocol used for connection trino
username Username for connection lucy
hostname Hostname or IP address where the Trino server is running mysecretpassword
port Port number on which the Trino server is listening 8080
catalog=<catalog_name> The catalog in Trino that you're connecting to. hive
schema=<schema_name> The schema within the catalog that you're connecting to myschemaname

The account identifier depends upon your Trino account edition. For information, see the Trino Documentation.

The following shows an example for the dsn portion:

dsn: "http://trino@localhost:8080?catalog=tpch&schema=sf1"

SingleStore configuration

For SingleStore databases, you must pass the DSN that contains the connection information for that SingleStore database:

configurationset:
  - configuration:
      name: singlestore_config
      dsn: "username:password@tcp(hostname)/database_name?tls=true"
The dsn value can include the parameters listed in Table 9:
Table 9. Parameters for the dsn value in a SingleStore configuration
dsn Value Description Example
username Your username john
password Your database password secretpassword
hostname Your host specification tcp(us.address.from.deployment.service)
dbname Your database name mydbname
tls Enables TLS / SSL encrypted connection to the server tls=true

For information, see the SingleStore Documentation.

The following shows an example for the dsn portion:

dsn: john:secretpassword@tcp(us.address.from.deployment.service)/mydbname?tls=true

Using environment variables in the config.yaml file

You can use environment variables within your config.yaml file. This enables you to keep sensitive information such as API keys and DSN strings outside of your code base, while still leveraging it within your schema configuration. The only rule is that the environment variable name must include the STEPZEN_ prefix.

If there is a .env file in the project folder, the CLI automatically loads all environment variables defined there that are not already set in the CLI environment.

For example, if you store the DSN information or a MySQL connection within a .env file as follows:

STEPZEN_MYSQL_DSN=username:password@tcp(us-cdbr-east-03.cleardb.com)/database_name

You can then reference the value of STEPZEN_MYSQL_DSN within a configuration inside config.yaml:

configurationset:
  - configuration:
      name: mysql_config
      dsn: STEPZEN_MYSQL_DSN

This doesn't just apply to DSN configurations; you can use environment variables in place of API keys as well.

Using Authorization headers in the GraphQL schema

In some cases, such as when running a @sequence directive, GraphQL arguments can be passed as header variables in an HTTP request. In the following example, an argument of access_token: String is passed to the Authorization header as a bearer token:

type Query {
    id: String 
}

type Query {
    my_query(access_token: String): Query
        @rest (
            endpoint: "https://api.example.com/v1/api/"
            headers: [{ name: "Authorization", value: "$access_token" }]
        )
}
Query
When running the GraphQL query, the access_token: String argument is "Bearer <YOUR_ACCESS_TOKEN>" where <YOUR_ACCESS_TOKEN> must be replaced by your own access token, and contain the entire string for the Authorization header:
query MyQuery {
  my_query(
    access_token: "Bearer <YOUR_ACCESS_TOKEN>"
  ) {
    id
  }
}

If the access_token argument is not provided in the query, or if it is explicitly set to null, API Connect for GraphQL resolves the Authorization header to an empty string, "".

This is an example query where there is no access_token argument provided:

query MyQuery {
  my_query {
    id
  }
}

Authorization: "null" is converted to Authorization: "" to prevent server errors and avoid sending unwanted null arguments as headers.

Combining variables with strings in Authorization headers
API Connect for GraphQL also supports strings combined with variables in header arguments.

As shown in the following schema, my_query will combine the GraphQL argument access_token with a literal string Bearer:

my_query(access_token: String): Query
        @rest (
            endpoint: "https://api.example.com/v1/api/"
            headers: [{ name: "Authorization", value: "Bearer $access_token" }]
        )

When my_query is executed, access_token does not need to contain the Bearer string. The schema combines the Bearer string with the access_token:

query MyQuery {
  my_query(
    access_token: "CMORsM63LxIO_4eBAEBAgAAMAEAAAAYY_MDnCSCXsaQLKM_AFzIUdnIEl9qo7Cwj2t1Z_rNAec5zYls6LgB_b8f_BwyE_wf8_-D_fc4sAAAAYAYY9DwfIBgcgA_gwx8GGQAAOIUnAADgAOBCFBZjpguluSl9IBk0ni7_U1o-pPgjSgNuYTFSAFoA"
  ) {
    id
  }
}

The request going to the endpoint https://api.example.com/v1/api/ still sends the Authorization header the same way it did previously ("Authorization": "Bearer CMORsM63LxIO...").

@sequence example: passing access_token as a variable
Let's say there is an @sequence directive that sends the access_token but does not provide the token type Bearer in the string.
Tip: See Creating a sequence of GraphQL queries to understand how this sequence passes variables between queries.

You do not need to understand @sequence in full detail to know how API Connect for GraphQL uses the access_token to support Authorization headers in this example.

type Auth {
    access_token: String!
    token_type: String!
    expires_in: String!
}

type Query {
    id: String 
}

type Query {
    get_auth: Auth
        @rest(
            method: POST
            contenttype: "application/x-www-form-urlencoded"
            endpoint: "https://api.example.com/v1/api?username={{.Get \"username\" }}&password={{.Get \"password\" }}"
            configuration: "configs"
        )
    my_query(access_token: String): Query
        @rest (
            endpoint: "https://api.example.com/v1/api/"
            headers: [{ name: "Authorization", value: "Bearer $access_token" }]
        )
    """
    returns a query with the new access_token
    """
    query_with_key: Query
        @sequence(
            steps: [
                { query: "get_auth" }
                { query: "my_query" }
            ]
        )
}

The type Auth has the field access_token, and in the query_with_key @sequence, the get_auth query passes the access_token to the my_query query.

{
    "token_type": "bearer",
    "refresh_token": "12314-3ee9-4a6b-bc87-134254332",
    "access_token": "CMORsM63LxIO_4eBAEBAgAAMAEAAAAYY_MDnCSCXsaQLKM_AFzIUdnIEl9qo7Cwj2t1Z_rNAec5zYls6LgB_b8f_BwyE_wf8_-D_fc4sAAAAYAYY9DwfIBgcgA_gwx8GGQAAOIUnAADgAOBCFBZjpguluSl9IBk0ni7_U1o-pPgjSgNuYTFSAFoA",
    "expires_in": 21600
}

As shown in the preceding section, access_token generated by the first step (using get_auth), does not have Bearer preceding the token generated, so my_query must be written with headers: [{ name: "Authorization", value: "Bearer $access_token" }]. API Connect for GraphQL combines the variable access_token being passed in the first step with Bearer added in the schema to properly execute the Authorization header.

my_query(access_token: String): Query
        @rest (
            endpoint: "https://api.example.com/v1/api/"
            headers: [{ name: "Authorization", value: "Bearer $access_token" }]
        )