Back to Examples
- Binding patterns
- Typed binding pattern
- Wildcard binding pattern
- List binding patterns
- Rest binding pattern in list binding pattern
- Mapping binding pattern
- Rest binding pattern in mapping binding pattern
- Error binding pattern
- Rest binding pattern in error binding pattern
- Single use of typed binding patterns
- Single use of typed binding patterns with on fail clause
- Iterative use of typed binding patterns
- List binding pattern in match statement
- Mapping binding pattern in match statement
- Error binding pattern in match statement
- Query expressions
- Sort iterable objects
- Let clause
- Limit clause
- Join iterable objects
- Outer Join clause
- Query tables
- Create tables with a query
- Create maps with a query
- Create streams with a query
- On conflict clause
- Advanced conflict handling
- Iterate over XML with a query
- Nested query expressions
- Destructure records using a query
- Querying streams
- Aggregation
- JSON type
- Access JSON elements
- Access optional JSON elements
- Match statement with maps
- Convert from user-defined type to JSON
- Convert from table and XML to JSON
- Convert from JSON to user-defined type
- Cast JSON to user-defined type
- Resource method typing
- JSON numbers
- JSON to record
- JSON to record with projection
- JSONPath expressions
- Asynchronous function calls
- Named workers
- Sequence diagrams
- Wait for workers
- Strands
- Named worker return values
- Alternate wait
- Multiple wait
- Named workers and futures
- Inter-worker message passing
- Alternate receive
- Multiple receive
- Conditional send
- Inter-worker failure propagation
- Named worker with on fail clause
- Synchronize message passing
- Asynchronize message passing
- Flush
- Fork
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
- • Start an instance of the NATS server.
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.