VRL (Custom Plugins)
To simplify the process of extending the functionality of the GraphQL Gateway, we adopted a Rust-based script language called VRL.
VRL language is intended for writing simple scripts that can be executed in the context of the GraphQL Gateway. VRL is focused around safety and performance: the script is compiled into Rust code when the server starts, and executed as a native Rust code (you can find a comparison between VRL and other scripting languages here).
VRL was initially created to allow users to extend Vector, a high-performance observability data router, and adopted for Conductor to allow developers to extend the functionality of the GraphQL Gateway easily.
Writing VRL
VRL is an expression-oriented language. A VRL program consists entirely of expressions, with every expression returning a value. You can define variables, call functions, and use operators to manipulate values.
Variables and Functions
The following program defines a variable myVar
with the value "myValue"
and prints it to the console:
myVar = "my value"
log(myVar, level:"info")
Assignment
The .
is used to set output values. In this example, we are setting the x-authorization
header of the upstream HTTP request to my-value
.
Here’s an example for a VRL program that extends Conductor’s behavior by adding a custom HTTP header to all upstream HTTP requests:
.upstream_http_req.headers."x-authorization" = "my-value"
Metadata
The %
is used to access metadata values. Note that metadata values are read only.
The following program is printing a metadata value to the console:
log(%downstream_http_req.headers.authorization, level:"info")
Further Reading
Runtime Failure Handling
Some VRL functions are fallible, meaning that they can error. Any potential errors thrown by fallible functions must be handled, a requirement enforced at compile time.
# This function is fallible, and can create errors, so it must be handled.
parsed, err = parse_json("invalid json")
VRL function calls can be marked as infallible by adding a !
suffix to the function call: (note that this might lead to runtime errors)
parsed = parse_json!("invalid json")
In case of a runtime error of a fallible function call, an error will be returned to the end-user, and the gateway will not continue with the execution.
Input/Output
on_downstream_http_request
The on_downstream_http_request
hook is executed when a downstream HTTP request is received to the gateway from the end-user.
The following metadata inputs are available to the hook:
-
%downstream_http_req.body
(type:string
): The body string of the incoming HTTP request. -
%downstream_http_req.uri
(type:string
): The URI of the incoming HTTP request. -
%downstream_http_req.query_string
(type:string
): The query string of the incoming HTTP request. -
%downstream_http_req.method
(type:string
): The HTTP method of the incoming HTTP request. -
%downstream_http_req.headers
(type:object
): The HTTP headers of the incoming HTTP request.
The following output values are available to the hook:
-
.graphql.operation
(type:string
): The GraphQL operation string to be executed. If this value is set, the gateway will skip the lookup phase, and will use this GraphQL operation instead. -
.graphql.operation_name
(type:string
): If multiple GraphQL operations are set in.graphql.operation
, you can specify the executable operation by setting this value. -
.graphql.variables
(type:object
): The GraphQL variables to be used when executing the GraphQL operation. -
.graphql.extensions
(type:object
): The GraphQL extensions to be used when executing the GraphQL operation.
on_downstream_graphql_request
The on_downstream_graphql_request
hook is executed when a GraphQL operation is extracted from a downstream HTTP request, and before the upstream GraphQL request is sent.
The following metadata inputs are available to the hook:
-
%downstream_graphql_req.operation
(type:string
): The GraphQL operation string, as extracted from the incoming HTTP request. -
%downstream_graphql_req.operation_name
(type:string
) : If multiple GraphQL operations are set in%downstream_graphql_req.operation
, you can specify the executable operation by setting this value. -
%downstream_graphql_req.variables
(type:object
): The GraphQL variables, as extracted from the incoming HTTP request. -
%downstream_graphql_req.extensions
(type:object
): The GraphQL extensions, as extracted from the incoming HTTP request.
The following output values are available to the hook:
-
.graphql.operation
(type:string
): The GraphQL operation string to be executed. If this value is set, it will override the existing operation. -
.graphql.operation_name
(type:string
): If multiple GraphQL operations are set in.graphql.operation
, you can override the extracted value by setting this field. -
%downstream_graphql_req.variables
(type:object
): The GraphQL variables, as extracted from the incoming HTTP request. Setting this value will override the existing variables. -
%downstream_graphql_req.extensions
(type:object
): The GraphQL extensions, as extracted from the incoming HTTP request. Setting this value will override the existing extensions.
on_upstream_http_request
The on_upstream_http_request
hook is executed when an HTTP request is about to be sent to the upstream GraphQL server.
The following metadata inputs are available to the hook:
-
%upstream_http_req.body
(type:string
): The body string of the planned HTTP request. -
%upstream_http_req.uri
(type:string
): The URI of the planned HTTP request. -
%upstream_http_req.query_string
(type:string
): The query string of the planned HTTP request. -
%upstream_http_req.method
(type:string
): The HTTP method of the planned HTTP request. -
%upstream_http_req.headers
(type:object
): The HTTP headers of the planned HTTP request.
The following output values are available to the hook:
-
.upstream_http_req.body
(type:string
): The body string of the planned HTTP request. Setting this value will override the existing body. -
.upstream_http_req.uri
(type:string
): The URI of the planned HTTP request. Setting this value will override the existing URI. -
.upstream_http_req.query_string
(type:string
): The query string of the planned HTTP request. Setting this value will override the existing query string. -
.upstream_http_req.method
(type:string
): The HTTP method of the planned HTTP request. Setting this value will override the existing HTTP method. -
.upstream_http_req.headers
(type:object
): The HTTP headers of the planned HTTP request. Headers set here will only extend the existing headers. You can usenull
value if you wish to remove an existing header.
on_downstream_http_response
The on_downstream_http_response
hook is executed when a GraphQL response is received from the upstream GraphQL server, and before the response is sent to the end-user.
The following metadata inputs are available to the hook:
-
%downstream_http_res.body
(type:string
): The body string of the HTTP response. -
%downstream_http_res.status
(type:number
): The status code of the HTTP response. -
%downstream_http_res.headers
(type:object
): The HTTP headers of the HTTP response.
The following output values are available to the hook:
-
.downstream_http_res.body
(type:string
): The body string of the HTTP response. Setting this value will override the existing body. -
.downstream_http_res.status
(type:number
): The status code of the HTTP response. Setting this value will override the existing status code. -
.downstream_http_res.headers
(type:object
): The HTTP headers of the HTTP response. Headers set here will only extend the existing headers. You can usenull
value if you wish to remove an existing header.
Shared State
During the execution of VRL programs, Conductor configures a shared state object for every incoming HTTP request.
This means that you can create type-safe shared state objects, and use them to share data between different VRL programs and hooks.
You can find an example for this in the Examples section below.
Available Functions
Configuration
Examples
Load and execute VRL plugins using inline configuration.
YAML
config:
on_upstream_http_request:
content: |
.upstream_http_req.headers."x-authorization" = "some-value"
from: "inline"
enabled: true
type: "vrl"
JSON
{
"config": {
"on_upstream_http_request": {
"content": ".upstream_http_req.headers.\"x-authorization\" = \"some-value\"\n ",
"from": "inline"
}
},
"enabled": true,
"type": "vrl"
}
Reference
on_downstream_http_request
A hook executed when a downstream HTTP request is received to the gateway from the end-user. This hook allow you to extract information from the request, for later use, or to reject a request quickly.
inline
Inline string for a VRL code snippet. The string is parsed and executed as a VRL plugin.
from
inline
To use this variation, please specify the type: inline
in your configuration.
content
file
File reference to a VRL file. The file is loaded and executed as a VRL plugin.
from
file
To use this variation, please specify the type: file
in your configuration.
path
on_downstream_graphql_request
A hook executed when a GraphQL query is extracted from a downstream HTTP request, and before the upstream GraphQL request is sent. This hooks allow you to easily manipulate the incoming GraphQL request.
inline
Inline string for a VRL code snippet. The string is parsed and executed as a VRL plugin.
from
inline
To use this variation, please specify the type: inline
in your configuration.
content
file
File reference to a VRL file. The file is loaded and executed as a VRL plugin.
from
file
To use this variation, please specify the type: file
in your configuration.
path
on_upstream_http_request
A hook executed when an HTTP request is about to be sent to the upstream GraphQL server. This hook allow you to manipulate upstream HTTP calls easily.
inline
Inline string for a VRL code snippet. The string is parsed and executed as a VRL plugin.
from
inline
To use this variation, please specify the type: inline
in your configuration.
content
file
File reference to a VRL file. The file is loaded and executed as a VRL plugin.
from
file
To use this variation, please specify the type: file
in your configuration.
path
on_downstream_http_response
A hook executed when a GraphQL response is received from the upstream GraphQL server, and before the response is sent to the end-user. This hook allow you to manipulate the end-user response easily.
inline
Inline string for a VRL code snippet. The string is parsed and executed as a VRL plugin.
from
inline
To use this variation, please specify the type: inline
in your configuration.
content
file
File reference to a VRL file. The file is loaded and executed as a VRL plugin.
from
file
To use this variation, please specify the type: file
in your configuration.
path