To access the data in your backends via StepZen, you need to specify authentication and connection properties such as usernames, passwords, DSN, authorizations, and so on.
The following sections describe how to specify that information:
- What is config.yaml?
- Authorization Headers in the GraphQL Schema: How to pass authorization headers via GraphQL arguments.
What's a config.yaml?
You specify authentication and connection information by passing it to the appropriate connector (@rest
, @dbquery
, or @graphql). These are managed in a single file named
config.yaml`.
The config.yaml
file must be placed in the root of your StepZen project, at the same level as your index.graphql
file:
my-stepzen-folder . ├── index.graphql ├── config.yaml └── schemas
config.yaml
is written in YAML to relay information regarding your configuration and keys to StepZen. 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
may 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.
The following subsections provide additional details about config.yaml
files:
- REST Configurations
- Pass an API key via the Authorization Header
- Pass Additional Header Values
- Database Configuration
- Environment Variables
REST Configurations
If a REST service is public and you do not need an API key, you may 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
(e.g., remotesynth
).
Pass an API key via the Authorization Header
If a REST service requires an API key that is passed using the Authorization
header, pass it via 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 via named keys other than the Authorization
header. Pass these in the header by prepending header.
to the key name:
configurationset: - configuration: name: dev_config header.api-key: MY_API_KEY
Database Configuration
The database configuration is important. Without it, StepZen can't access your deployed database. StepZen currently supports connections to MySQL, PostgreSQL, and MSSQL databases. MySQL and PostgreSQL require a slightly different type of configuration as described in the following subsections:
Note: Reach out to us on Discord if you are having any trouble connecting to your database.
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 following parameters:
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 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
Postgres 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 following parameters:
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 (like
#$%&
) to be URL-encoded. If your password is, for examplepa$$word
, it needs to be encoded aspa%24%24word
. Quotes around theuri
are required when it is URL-encoded. You can use the tool urlencoder.org to encode your password.
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 following parameters:
dsn Value | Description | Example |
---|---|---|
sqlserver:// | You can leave the sqlserver:// part of the uri as it 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 following parameters:
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"
Environment Variables
You can use environment variables within your StepZen 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 be prefaced with a STEPZEN_
.
If there is a .env
file in the project folder, StepZen CLI automatically loads all environment variables defined there that are not already set in the CLI's 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
Note: This doesn't just apply to DSN configurations. You can use environment variables in place of API keys as well.
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 example below, 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
, StepZen 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.
Combine Variables with Strings in Authorization Headers
StepZen also supports strings combined with variables in header arguments.
As shown in the schema below, 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 of Passing access_token as a Variable
Let's say there is an @sequence
that sends the_access_token
but does not provide the token type Bearer
in the string.
Note: Refer to the @sequence documentation to understand how this sequence passes variables between queries.
You do not need to understand @sequence
in full detail to know how StepZen 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" } ] ) }
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 above, 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" }]
. StepZen 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" }] )