Back to Examples

NATS service - Constraint validation

The Ballerina constraint module allows you to add additional constraints to the message content. The constraints can be added to a given data type using different annotations. When a message with a constraint is received from the NATS server, it is validated internally. This validation happens soon after the successful data-binding of the message content before executing the onMessage remote method. If the validation fails, the onError remote method is invoked with the error type nats:PayloadValidationError. Use this to validate the message content as the application receives it, which allows you to guard against unnecessary remote method processing and malicious content.

import ballerina/constraint;
import ballerina/log;
import ballerinax/nats;

public type Order record {
    int orderId;
    // Add a constraint to allow only string values of length between 1 and 30.
    @constraint:String {maxLength: 30, minLength: 1}
    string productName;
    decimal price;
    boolean isValid;
};

// Binds the consumer to listen to the messages published to the 'orders.valid' subject.
service "orders.valid" on new nats:Listener(nats:DEFAULT_URL) {

    remote function onMessage(Order 'order) returns error? {
        if 'order.isValid {
            log:printInfo(string `Received valid order for ${'order.productName}`);
        }
    }

    // When an error occurs, `onError` gets invoked.
    remote function onError(nats:AnydataMessage message, nats:Error err) {
        if err is nats:PayloadValidationError {
            log:printError("Payload validation failed", err);
        }
    }
}

Prerequisites

Run the service by executing the following command.

$ bal run nats_service_constraint_validation.baltime = 2022-12-05T08:44:43.093+05:30 level = INFO module = "" message = "Received valid order for Sport shoe"time = 2022-12-05T08:45:03.136+05:30 level = ERROR module = "" message = "Payload validation failed" error = "Validation failed for \'$.productName:maxLength\' constraint(s)."time = 2022-12-05T08:45:19.702+05:30 level = INFO module = "" message = "Received valid order for Sport shoe"

Tip: You can invoke the above service via the NATS client example with a valid product name (0 < length <= 30), then with an invalid product name and again with a valid product name.

Related links

PreviousSend reply to request message
NextConsume JetStream message