Consider the scenario where we create a record for capturing a JSON payload. (application/json
content type)
Is there any benefit of using a closed record with a JSON type rest descriptor over an open record?
Since JSON
allows any primitive types and their derived array/record (object) assignment, and the record is only used for capturing a JSON payload, restricting it as a closed record seems redundant. (Only a few types like XML
, query
(SQL) will be restricted which cannot pass from application/json
content)
E.g.:
type Person record {|
string name;
int age;
json...;
|}
vs.
type Person record {
string name;
int age;
}
Both of these are open records.
type Person record {
string name;
int age;
}
is equivalent to
type Person record {|
string name;
int age;
anydata...;
|}
So the difference here is a rest descriptor of json
vs anydata
.
Having a more specific type is a better reflection of the possible values. Without the explicit rest descriptor (json...
) the type says (additional/rest) field values can be anydata
(therefore, can be table and xml too), but that isn't the case here.
With just response data binding to extract only the specified fields, it wouldn't make much of a difference either way. But, if you need to use Person
in a context that expects a json
value, if you open it with anydata
, you'll have to do an extra conversion, which can be expensive.
E.g.,
import ballerina/http;
type E1 record {
int id;
string name;
};
type E2 record {|
int id;
string name;
json...;
|};
// http:Request.setJsonPayload expects a `json` value as the argument
function f1(http:Request req, E1 e1) {
req.setJsonPayload(e1); // error
req.setJsonPayload(e1.toJson()); // OK, but needs a conversion
}
function f2(http:Request req, E2 e2) {
req.setJsonPayload(e2); // OK, without a conversion
}