Skip to content

Refactor role handling: Introduce JsonPartialRole and PartialRole for improved deserialization - #413

Open
jedrek0429 wants to merge 9 commits into
NetCordDev:mainfrom
jedrek0429:fix-invite-roles-deserialisation
Open

Refactor role handling: Introduce JsonPartialRole and PartialRole for improved deserialization#413
jedrek0429 wants to merge 9 commits into
NetCordDev:mainfrom
jedrek0429:fix-invite-roles-deserialisation

Conversation

@jedrek0429

Copy link
Copy Markdown
Contributor

No description provided.

@KubaZ2

KubaZ2 commented Sep 12, 2026

Copy link
Copy Markdown
Member

Thanks, could you explain why this is even needed? There are many cases in which Discord returns some partial objects, and it so far worked that we just used default values for the omitted properties. That way we don't introduce an additional complexity when it is not needed.

@jedrek0429

jedrek0429 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, could you explain why this is even needed? There are many cases in which Discord returns some partial objects, and it so far worked that we just used default values for the omitted properties. That way we don't introduce an additional complexity when it is not needed.

Suppose an invite grants an Administrator role. Discord sends the id, the name, etc. but deliberately does not send permissions. Then if NetCord constructs a normal Role from that payload you can write invite.Roles[0].Permissions and you get:

Permissions.None

That statement is false. Discord did not tell us that the role has no permissions, it told us nothing about its permissions. It's just a semantic problem.

Additionally the existing Role is documented as “Represents a role in a guild” and exposes all of those properties as if they were authoritative. So defaulting leaks through the public API as apparently real data.

There is also precedence: PartialGuildUser, for example, explicitly represents a guild user lacking GuildId and methods depending on it, while GuildUser derives from it. That said, if NetCord intentionally treats omitted fields this way and prefers keeping one model for the "same" conceptual Discord object, then I agree this may be more complexity than the library wants.

As to why this specific class drew my attention, I was just checking recent api changelog entries against NetCord and found this mismatch, and the implementation is very small.

@KubaZ2

KubaZ2 commented Sep 12, 2026

Copy link
Copy Markdown
Member

I think your concerns are generally valid, nobody wants to get invalid data. Are you sure there are no more cases in which returned roles are partial in the API? Also I think ideally it should be Role : PartialRole and PartialRole gets all the RestClient aliases generated.

Also PartialGuildUser is a slightly different case. Due to the fact it doesn't have the GuildId available, there is no way for it to have RestClient aliases. That's the main reason it exists.

@jedrek0429

Copy link
Copy Markdown
Contributor Author

Also I think ideally it should be Role : PartialRole and PartialRole gets all the RestClient aliases generated.

I think this could become awkward because PartialRole is an Entity whilst Role is a ClientEntity, so PartialRole would need an overload constructor just for Role, and would need to contain the RestClient it doesn't need. That's why I opted for a joint interface implementation instead of class inheritance.

@KubaZ2

KubaZ2 commented Sep 12, 2026

Copy link
Copy Markdown
Member

I think this could become awkward because PartialRole is an Entity whilst Role is a ClientEntity, so PartialRole would need an overload constructor just for Role, and would need to contain the RestClient it doesn't need. That's why I opted for a joint interface implementation instead of class inheritance.

Not awkward at all, PartialRole needs RestClient anyway for RestClient aliases. Also ClientEntity is only a nice helper class so that each object that requires a RestClient doesn't need its own property for it written manually.

@github-actions

Copy link
Copy Markdown

The documentation preview is available at https://preview.netcord.dev/413.

Comment thread NetCord/JsonModels/JsonRole.cs Outdated
Comment thread NetCord/Rest/RestClient.Guild.cs Outdated
Comment thread NetCord/PartialRole.cs Outdated
Comment thread NetCord/PartialRole.cs
Comment thread NetCord/Role.cs Outdated
@jedrek0429 jedrek0429 changed the title Refactor role handling: Introduce JsonPartialRole and IPartialRole interface for improved deserialization Refactor role handling: Introduce JsonPartialRole and PartialRole for improved deserialization Sep 13, 2026
Removed duplicate GenerateAlias attribute for Role in ModifyGuildRoleAsync method.
…redundant XML comments, and move JsonPartialRole to a separate file
@jedrek0429

Copy link
Copy Markdown
Contributor Author

@KubaZ2 this is now fully ready

@jedrek0429
jedrek0429 requested a review from KubaZ2 September 14, 2026 10:51
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.

2 participants