Skip to content
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

Operator Create Network Area #382

Merged
merged 15 commits into from
Oct 25, 2024

Conversation

larrytamnjong
Copy link
Contributor

@@ -100,6 +100,34 @@ public class KeyringResponse
public int NumNodes { get; set; }
}

public class Area
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please split it into two structures, one for request and one for response.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve just completed it. Please let me know if everything looks good.

public bool UseTLS { get; set; }
}

public class AreaResponse : Area
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inheritance is not needed here, please remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @marcin-krystianc Initially, I considered using inheritance because, in certain cases like the List Specific Network Area response, additional properties such as PeerDatacenter and RetryJoin are returned. I thought that inheriting from the Area class would make the response more flexible for these scenarios.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @marcin-krystianc Initially, I considered using inheritance because, in certain cases like the List Specific Network Area response, additional properties such as PeerDatacenter and RetryJoin are returned. I think inheriting from the Area class will make the response more flexible for these scenarios.

Ah, I see. It is tempting to reuse existing structure definitions for new ones to save some code, but in my opinion, it isn't always the right thing to do. Given that apart from Create Network Area there are other methods like List Network Areas, Update Network Area, and others - we need to plan how we are going to define requests and responses for all of them.
My initial plan was to create a dedicated request and response structure definition for each method. That would give us full control over those structures and would define the interface very clearly from a user perspective (It is more code in the library to write but it is very straightforward).
On the other hand, I looked at the consul implementation of Operator_Area API (https://github.com/hashicorp/consul/blob/main/api/operator_area.go) and maybe it is ok to do it similarly.
It would require fewer structure definitions but I guess the API will be less clear from the user perspective (for example AreaUpdate methods take ID and Area objects, but Area has already an ID but it is not used).

I think I'll leave it to you to decide. Both approaches have pros and cons

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the insights @marcin-krystianc ! I initially removed the inheritance and made adjustments based on your initial recommendations, but since you're leaving it up to me, I've added it back. Please let me know what you think!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of inheritance somewhat bothers me, but maybe unnecessarily :-) The only suggestion I have is to change the names: Area -> AreaRequest and AreaResponse -> Area

@@ -45,6 +45,8 @@ public interface IOperatorEndpoint
Task<QueryResult<ConsulLicense>> GetConsulLicense(string datacenter = "", CancellationToken ct = default);
Task<QueryResult<string[]>> SegmentList(QueryOptions q, CancellationToken cancellationToken = default);
Task<QueryResult<string[]>> SegmentList(CancellationToken cancellationToken = default);
Task<WriteResult<string>> CreateArea(Area area, WriteOptions q, CancellationToken ct = default);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result type should be Task<WriteResult<AreaResponse>>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result type should be Task<WriteResult<AreaResponse>>

When I made that comment I assumed that AreaResponse will contain only an ID field.

public bool UseTLS { get; set; }
}

public class AreaResponse : Area
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of inheritance somewhat bothers me, but maybe unnecessarily :-) The only suggestion I have is to change the names: Area -> AreaRequest and AreaResponse -> Area

public async Task<WriteResult<AreaResponse>> CreateArea(Area area, WriteOptions q, CancellationToken ct = default)
{
var req = await _client.Post<Area, AreaResponse>("/v1/operator/area", area, q).Execute(ct).ConfigureAwait(false);
return new WriteResult<AreaResponse>(req, req.Response);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning an object, where only the ID field will be initialised, but others will be not - is not great from the usability perspective. (It is confusing, to se a struct which is not fully initialised, you need an extra effort to refer to docs or to implementation to understand why is that)
In the go implementation (https://github.com/hashicorp/consul/blob/main/api/operator_area.go#L91), the Create method returns string, so I guess that what we also should do(i.e. return new WriteResult<string>(req, req.Response.ID)).

Initially I wanted a dedicated struct for response, because I anticipated other fields being added to the response. But since go implementation returns only a single string, we can do it too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much, @marcin-krystianc for the detailed explanation and guidance! 😊 I've made the changes you suggested. Please let me know if there’s anything else I should adjust.

public class Area : AreaRequest
{
/// <summary>
/// ID is this identifier for an area (a UUID). This must be left empty
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With our API, the comment This must be left empty when creating a new area. is not relevant.

@@ -249,6 +280,25 @@ public Task<QueryResult<string[]>> SegmentList(CancellationToken ct = default)
{
return SegmentList(QueryOptions.Default, ct);
}

/// <summary>
/// CreateArea will create a new network area. The ID in the given structure must
Copy link
Contributor

@marcin-krystianc marcin-krystianc Oct 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here as well it is not relevant for our API -> The ID in the given structure must be empty and a generated ID will be returned on success.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks.

larrytamnjong and others added 2 commits October 25, 2024 10:00
Update documentation comment

Co-authored-by: Marcin Krystianc <[email protected]>
Update documentation comment

Co-authored-by: Marcin Krystianc <[email protected]>
Copy link
Contributor

@marcin-krystianc marcin-krystianc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now, thanks for bearing with me.

@marcin-krystianc marcin-krystianc merged commit c4c0fab into G-Research:master Oct 25, 2024
243 checks passed
@larrytamnjong larrytamnjong deleted the create-network-area branch October 28, 2024 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants