Contact Us 1-800-596-4880

Using DataWeave Expressions

To view an example policy project that uses DataWeave expressions, see Query Policy Example.

If the input DataWeave expression parameter is valid, the policy parses the expression and transforms it into a pdk::script::Script expression. To obtain the result of the script:

  1. Create an evaluator.

  2. Call the binding function for each parameter defined in the schema definition:

    • vars: Call the bind_vars method for each of the policy’s vars. After all of vars are bound, the evaluator tries to solve the expression. If the expression contains vars other than the ones defined in the schema, they resolve to null.

    • attributes: Call the bind_attributes method with an implementation of the AttributesBinding trait. Flex Gateway Policy Development Kit (PDK) provides an implementation of this trait by instantiating a new HandlerAttributesBinding for each RequestHeaderState, RequestHeaderState, and response of an HTTP call.

    • authentication: Call the bind_authentication method with an implementation of the trait AuthenticationBinding. PDK provides an implementation of this trait for AuthenticationData. To inject authentication information into your policy, see Inject Authentication Inforamaion.

    • payload: Call the bind_payload method with an implementation of the trait PayloadBinding. PDK provides an implementation of this trait for RequestBodyState, ResponseBodyState, and the response of an HTTP call.

      Call only the methods for the bindings defined in the schema definition. For example, if the attributes binding is not used, don’t call the bind_attributes method.

      To learn more about defining DataWeave expressions, see DataWeave Expressions.

  3. After you bind all expression variables, obtain the result by calling the eval method.

Evaluate DataWeave Expressions

For example, to evaluate the tokenExtractor DataWeave expression in the following policy schema definition:

apiVersion: gateway.mulesoft.com/v1alpha1
kind: Extension
metadata:
 labels:
   title: jwt-auth
   category: Custom
spec:
 extends:
   - name: extension-definition
     namespace: default
 properties:
   tokenExtractor:
     type: string
     format: dataweave
     default: "#[vars.myVar]"
     bindings:
       payload:
         mimeType: text
       attributes: true
       authentication: true
       vars:
         - myVar
 required:
   - tokenExtractor

Use the following Rust snippet:

// Copyright 2024 Salesforce, Inc. All rights reserved.
mod generated;


use anyhow::Result;


use crate::generated::config::Config;
use pdk::authentication::{Authentication, AuthenticationHandler};
use pdk::logger::info;
use pdk::hl::*;
use pdk::script::{Evaluator, HandlerAttributesBinding, Value};


async fn request_filter(
   state: RequestState,
   stream: StreamProperties,
   auth: Authentication,
   mut evaluator: Evaluator<'_>,
) {
   evaluator.bind_vars("myVar", "myVal");

   evaluator.bind_authentication(&auth.authentication());

   let state = state.into_headers_state().await;
   evaluator.bind_attributes(&HandlerAttributesBinding::new(state.handler(), &stream));

   let state = state.into_body_state().await;
   evaluator.bind_payload(&state);

   if let Ok(value) = evaluator.eval() {
       match value {
           Value::Null => info!("value was null!"),
           Value::Bool(val) => info!("value was Bool: {val}"),
           Value::Number(val) => info!("value was Number: {val}"),
           Value::String(val) => info!("value was String: {val}"),
           Value::Array(val) => info!("value was Array: {val:?}"),
           Value::Object(val) => info!("value was Object: {val:?}"),
       }
   }
}


#[entrypoint]
async fn configure(launcher: Launcher, Configuration(bytes): Configuration) -> Result<()> {
   let config: Config = serde_json::from_slice(&bytes)?;


   launcher
       .launch(on_request(|request, stream, auth| {
           request_filter(request, stream, auth, config.token_extractor.evaluator())
       }))
       .await?;
   Ok(())
}

Validate the Expression was Resolved

You can resolve some expressions before all values are bound. For example, the expression #[vars.myVar] does not require the attributes, payload, no authentication to be resolved.

After one of the binding methods is called, you can confirm the expression was completely resolved by calling the method:

evaluator.is_ready()