I'm trying to read a json file and cast it to a custom defined record type which has constraints defined for the values in it.
The json file looks like follows,
[
{
"id": 1,
"username": "user1",
"password": "12345",
"name": "Sample User 1"
},
{
"id": 2,
"username": "user2",
"password": "12345",
"name": "Sample User 2"
},
{
"id": 3,
"username": "user3",
"password": "12345",
"name": "Sample User 3"
}
]
I defined a record type with constraints to fit to my requirements.
import ballerina/constraint;
type User record {|
int id;
string username;
@constraint:String {
minLength: 5
}
string password;
string name;
|};
The following is how I'm trying to fetch the data from the json file and trying to convert it to the record type.
import ballerina/io;
public function getUsers() returns User[]|error {
json data = check io:fileReadJson("<path-to-json-file>");
json copy = data.cloneReadOnly();
User[] users = <User[]>copy; // <-- Problematic line
return users;
}
The above code work fine if the record type has got no constraints.
My ultimate goal is to convert the above json file objects to defined type record if it matches and satisfy the constraints. If not it need to return error
CodePudding user response:
Casting (and/or lang library functions that do a conversion) do not do constraint validation against the annotations from the constraint
module. The ballerina/constraint
module is a standard library module and you would have to explicitly call constraint:validate
for the validation to happen against the constraints.
For example,
// Or `User[] & readonly` if the values need to be immutable.
User[] users = check data.cloneWithType();
foreach User user in users {
User|error validatedUser = constraint:validate(user);
if validatedUser is error {
// validation failed, and `validatedUser` will be of type `error` here
} else {
// validation was successful, `validatedUser` will be of type `User` here
}
}