-
Notifications
You must be signed in to change notification settings - Fork 741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Parameter Grouping to AutoRest for Azure.CSharp, Azure.NodeJS #381
Conversation
Can one of the admins verify this patch? |
1 similar comment
Can one of the admins verify this patch? |
Hi @matthchr, I'm your friendly neighborhood Azure Pull Request Bot (You can call me AZPRBOT). Thanks for your contribution!
TTYL, AZPRBOT; |
18230d7
to
105ea6a
Compare
@matthchr - It is a nice concept. As per the current implementation, the user can group parameters in 1 bucket. What if the user wants to group them into more than 1 bucket? Would it be a better idea if the extension takes a key value pair instead of a Boolean, something like this:
In this way the user can put parameters into different buckets if required. It also provides a flexibility to name the parameter group as per their requirement. What do you think? |
@amarzavery Yes, allowing more than one parameter group was something I thought about (if you see in the implementation the "groups" is actually a collection and everywhere when I generate the code I treat it as such), so the only thing currently stopping us from having multiple groups is the extension piece... With that said are some additional complications with allowing multiple parameter groups which is why I leaned against it initially:
I agree it would be good to have, but maybe leave it for a V2 implementation? edit: Okay I tried this and it turns out it was pretty easy to do (I thought it would be harder), so I added support for this right out of the box (and added some tests to make sure it works). Let me know what you think. |
Have you considered a more general approach? Rather than indirectly define a model type by grouping parameters, it would be really handy if we could bind some parameter values to others. For example, for PUT operations, it would be really nice to be able to bind the URL parameter for the resource ID to the corresponding property on the resource itself. See this issue for a concrete example: #382 |
@brjohnstmsft David Justice had discussed something similar to what you're asking for - he colloquially called it "parameter factories" or something. My team has a similar request, but instead of a "duplicate" parameter like in your example (where there is Model.Id and id), we want to set certain parameters to be automatically generated instead of including them in the signature. For example: parameter "string requestId" (required: true) could instead be optional or omitted entirely and automatically generated as a Guid (or in your case automatically generated from an existing model field). I do see the two things being different features though: this is about how to structure the parameters we do want, what you're asking for is a way to omit parameters which are "required" by the REST API but which you do not want. |
af20e76
to
73e51d2
Compare
add to whitelist |
|
||
foreach (Method method in serviceClient.Methods) | ||
{ | ||
//TODO: Does this group name need to be normalized later, or does that already happen? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it will be normalized by each code generator, so you are good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yugangw-msft Updated comment to reflect that fact
2acb4ee
to
6a03ddf
Compare
Okay, I moved the Parameters objects into the models folder and namespace. |
@yugangw-msft I am not sure why the "default" check failed in jenkins, can somebody help me take a look at that? Travis pass seems okay... |
@matthchr please merge with dev. The CI failure was caused by the java change made to the dev branch this afternoon |
6a03ddf
to
d09a149
Compare
@yugangw-msft Merge with dev done |
d09a149
to
d21bea0
Compare
@devigned @stankovski Should we use these comments to discuss proposed changes to this implementation? One thing that @xingwu1 pointed out to me is that this PR is pretty critical to our adoption, so I don't really want to have to re-design/re-do everything (especially if it's significantly more complicated to do an alternate way) because it will delay our swagger adoption (after this PR, we can actually generate a real client). If we can align on:
If we change the internals of AutoRest (the model structure) in the future to be more generic or cater to more scenarios, that change is fine because it's hidden from clients generated code and their swagger specifications. I'll start with my suggestion:
I think that the part which might be reusable is the stuff for the client model, but even that is maybe not totally code-reuse but rather just concept re-use... what I mean is this:
Let me know what you think. |
@@ -59,6 +59,27 @@ public Method() | |||
public List<Parameter> Parameters { get; private set; } | |||
|
|||
/// <summary> | |||
/// Gets the parameter groups. | |||
/// </summary> | |||
public IEnumerable<string> ParameterGroups |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be replaced with two "Mapping" properties - one for input and one for output.
@matthchr I agree with the approach. Let's leave swagger extension as-is. I also think that the generated code will stay almost the same. An output block of similar structure will be needed and you may need to convert terniary expression to an As far as mapping, I would leave current ParameterList as is and add a new data structure (either just a dictionanry or a class to work with output mapping) that matches an existing parameter or parameter property to a new parameter or parameter property. |
@stankovski I've created an issue #395 to discuss the structure of the returned object for the return header -> object path. Can we delay the implementation of that until we've decided on what the output object should look like (is it a union of the returned headers and the body, a <T, K> double-generic (in C#) or something else?). Until then, I think I won't be able to write any test cases or samples for the "re-grouping" case (since there will be no place to put the returned header seeing as the body is already populated by the JSON deserialization), so I will hold off on writing it. When we get there, we can follow the exact same pattern as the un-grouping case in this PR. Does that sound okay? |
d21bea0
to
e9d74c3
Compare
@stankovski This has the changes to ParameterGrouping to move to the "Mapping" idea -- the CI is failing due to an issue in dev branch -- once that is fixed I'll merge and update. |
@@ -59,6 +60,22 @@ public Method() | |||
public List<Parameter> Parameters { get; private set; } | |||
|
|||
/// <summary> | |||
/// Gets the list of Parameter Expansions | |||
/// </summary> | |||
public Dictionary<string, Dictionary<Property, Parameter>> ParameterExpansions { get; private set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make it more generic and support parameter groups as well primitive to object mapping can we do the following:
- Rename this to ParameterMappings
- Add new type to ClientModel called
ParameterMapping
with the following properties
Parameter InputParameter {get; set;}
string InputParameterProperty {get; set;}
(either null, which will map the parameter itself, or dot separated string to match properties)Parameter OutputParameter {get; set;}
string OutputParameterProperty {get; set;}
(either null, which will map the parameter itself, or dot separated string to match properties)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also add a public Parameter Body {get;}
to get easier access to the body parameter
dde26e6
to
357d061
Compare
- Support in C#, NodeJS, and partially in Java.
357d061
to
3791d93
Compare
Add Parameter Grouping to AutoRest for Azure.CSharp, Azure.NodeJS
* Add examples in body-string * Update examples * Update examples * Update package lock version * Update format
A "Parameter group" is just a nicer way to bundle parameters so that methods don't get horribly long. It is controlled by an extension to the Swagger specification.
Left out Ruby/Java for now, as Java doesn't have an "Azure.Java" yet and cut Ruby in the name of time (if/when somebody wants the feature in Ruby they should be able to follow the implementation from NodeJS/C#/Java since the metadata is in the client model now)