As flatten or spread concepts are quite confusing, this document will use below definition:
- spread body case: it means spreading a model using
...
, e.g.op(...AModel)
- flatten body case: it means defining request body without
@body
and not using spread syntax...
, e.g.op(a: AModel)
If a body parameter is defined without @body, TCGC will create an anonymous model with spread
usage for it, unless it is like case1, where there is only single spread body param, it will not create anonymous model, but reuse the spreaded model.
We reuse below definitions in below casese
model A {
p1: string;
p2: string;
}
model APatch {
p1?: string;
p2?: string;
}
op op1(...A);
TCGC return:
A: {
access: internal
usage: spread
}
code-model expected return:
A: {
usage: ["internal", "input"]
}
client method:
void op1(String p1, String p2);
op op1(a: A);
TCGC return:
Op1Request: {
access: internal
usage: spread
}
A: {
access: public
usage: input
}
code-model expected return:
A: {
usage: ["public", "input"]
}
Op1Request: {
usage: ["internal", "input"]
}
client method:
void op1(A a);
op op1(s: string, ...A);
TCGC return:
Op1Request: {
access: internal
usage: spread
}
code-model expected return:
Op1Request: {
usage: ["internal", "input"]
}
client method:
void op1(String, s, String p1, String p2);
op op1(s: string, a: A);
TCGC return:
Op1Request: {
access: internal
usage: spread
}
A: {
access: public
usage: input
}
code-model expected return:
Op1Request: {
usage: ["internal", "input"]
}
A: {
access: public
usage: input
}
client method:
void op1(String s, A a);
op op1(@path id: string, ...A);
TCGC return:
A: {
access: internal
usage: spread
}
code-model expected return:
A: {
usage: ["internal", "input"]
}
client method:
op1(String id, String p1, String p2);
op op1(@path id: string, a: A);
TCGC return:
Op1Request: {
access: internal
usage: spread
}
A: {
access: public
usage: input
}
code-model expected return:
Op1Request: {
usage: ["internal", "input"]
}
A: {
usage: ["public", "input"]
}
client method:
void op1(String id, A a);
op op1(
@header contentType: "application/merge-patch+json",
patch: APatch);
TCGC return:
Op1Request: {
access: internal
usage: spread
}
APatch: {
access: public
usage: [input, json-merge-patch]
}
code-model expected return:
Op1PatchRequest: {
access: public
usage: input
}
APatch: {
access: public
usage: input
}
client method:
void op1(Op1PatchRequest patch);
op op1(
@header contentType: "multipart/form-data",
body: bytes);
TCGC return:
Op1Request: {
access: internal
usage: [spread, multipart-form-data]
}
code-model expected return:
BodyFileDetails: {
access: public
usage: input
}
Op1Request: {
access: internal
usage: input
}
client method:
void op1(BodyFileDetails body);
op op1(...A);
op op2(a: A);
TCGC return:
A: {
access: public
usage: [input, spread]
}
Op2Request: {
access: internal
usage: spread
}
code-model expected return:
A: {
usage: ["public", "input"]
}
Op2Request: {
usage: ["internal", "internal"]
}
client method:
void op1(String p1, String p2);
void op2(A a);
We could treat TCGC returned spread
usage on model type as input
, but there remains two issues:
- case 7: flatten body + json-merge-patch, we don't know the access for
Op1PatchRequest
from operation. - case 8: flatten body + multipart, as we create our own multipart model
BodyFileDetails
, and tcgc returnsbytes
type for the body param, we can't know what is the access.
To unblock our adopting, for both cases, we can do two times processing. Logics like below:
- When processing operation, append the operation's access to the operation's body schema's access
- When processing model, append TCGC's access to the schema's access.
- Do a post processing to calculate the real access.
- case7 json-merge-patch: Haoling will check with .Net to see if they need the access info for json-merge-patch model as well, if they also need to have it, we can create an issue for TCGC to do it. The logic for TCGC is: If
Op1Request
's usage is spread+json-merge-path, and if it is Java or .Net, then TCGC markOp1Request
model aspublic
. - case8 multipart: I checked with .Net that they will no generate a model for the
bytes
body, so we don't ask TCGC to handle it. Srikanta will check the azure-core's progress. Finally we will use azure-core's model, and the issue does not exist.