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 yourconfiguration
; 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"
)
}
$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 theAuthorization
key of theconfiguration
: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 prefixingheader.
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:
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:
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:
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:
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:
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:
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:
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:
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"
dsn
value can include the parameters listed in Table
9:
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 theAuthorization
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 tonull
, API Connect for GraphQL resolves theAuthorization
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 toAuthorization: ""
to prevent server errors and avoid sending unwantednull
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 argumentaccess_token
with a literal stringBearer
: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 theBearer
string. The schema combines theBearer
string with theaccess_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 theAuthorization
header the same way it did previously ("Authorization": "Bearer CMORsM63LxIO..."
). @sequence
example: passingaccess_token
as a variable- Let's say there is an
@sequence
directive that sends theaccess_token
but does not provide the token typeBearer
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 theaccess_token
to supportAuthorization
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 fieldaccess_token
, and in thequery_with_key
@sequence
, theget_auth
query passes theaccess_token
to themy_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 (usingget_auth
), does not haveBearer
preceding the token generated, somy_query
must be written withheaders: [{ name: "Authorization", value: "Bearer $access_token" }]
. API Connect for GraphQL combines the variableaccess_token
being passed in the first step withBearer
added in the schema to properly execute theAuthorization
header.my_query(access_token: String): Query @rest ( endpoint: "https://api.example.com/v1/api/" headers: [{ name: "Authorization", value: "Bearer $access_token" }] )