-
Notifications
You must be signed in to change notification settings - Fork 506
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
exp/services/recoverysigner: remove type, add identities #2323
The head ref may contain hidden characters: "goodbye\u{1F44B}typesolongpeaceout\u270C\uFE0F"
exp/services/recoverysigner: remove type, add identities #2323
Conversation
### What Remove the `type` parameter stored alongside registered accounts and replace it with exposing information about which identities are set on an account to clients. ### Why The `type` existed purely for clients to get some sense of what purpose an account was registered, but it's really meta data about how a client is using the service and isn't necessarily a core concept for the service. The value was also synonymous with which identities are configured for an account. A `type` of `personal` will always have only an `owner` identity, and a `type` of `share` was always going to have an `other` identity alone or in addition to `owner`. By removing the concept of `type` and instead just giving a client visibility into which identities are set on the account we reduce the number of concepts a client has to learn and know about which makes the API simpler, even if the change appears to make the API slightly more complex.
Address: acc.Address, | ||
Identities: accountResponseIdentities{ | ||
Owner: accountResponseIdentity{ | ||
Present: acc.OwnerIdentities.Present(), | ||
}, | ||
Other: accountResponseIdentity{ | ||
Present: acc.OtherIdentities.Present(), | ||
}, | ||
}, |
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.
You'll notice this code block is duplicated a few times. I could reduce some code here, but I'm going to expend more effort holistically looking at reducing the duplicity here and in the authentication. Follow up: #2324.
👀 |
} | ||
|
||
type accountResponseIdentities struct { | ||
Owner accountResponseIdentity `json:"owner"` |
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.
I wonder if we can make these two fields omitempty
instead of using the Present
bool in another struct. If there's one field presented in the accountResponseIdentities
, then the client should be able to tell whether it's owner
or other
.
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.
I like that too, but our frontend team have mentioned before that it's much easier from a clients perspective is fields are always present and have a clear signal that something isn't available.
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.
Got it. If that's the case, would making it IsOwner bool
and IsOther bool
be sufficient?
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 is another way to solve the same goal, but it doesn't communicate the same intent. The account is not an owner, or an other, it has an owner identity, or an other identity.
If we ever want to expose more details about the owner or other the object let's us expand by adding more fields alongside present.
Do you have any specific concerns?
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.
I usually avoid having nested objects that are too deep. However, if the goal is to incorporate more fields in the future, it makes sense. I still feel like the cleanest way is to make it the way I suggested in the first place as Present
feels redundant. Let me confirm with the frontend team again.
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.
I like the omitempty approach too. If I do that, what do we do when the thing is present but has no fields? It will be like this: "owner": {}
which seems a bit odd and I think is harder to test for in JavaScript? Being able to do owner.present
for true
/false
explicitly seems really simple.
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 like this: "owner": {} which seems a bit odd and I think is harder to test for in JavaScript.
Maybe we can make the backend never do that?
Being able to do owner.present for true/false explicitly seems really simple.
Sure. It's not a blocker. Approving it.
|
||
// Present indicates if the Identities contains at least one identity. Returns | ||
// false if it is an empty/zero value. | ||
func (i Identities) Present() bool { |
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.
Nit: I personally like leading bool methods with Is
, just to make things clearer:
func (i Identities) Present() bool { | |
func (i Identities) IsPresent() bool { |
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.
I've liked this pattern too in other languages in the past, but in Go code it's more common to omit the Is
. Grabbing a random example the Response
type has Close
and Uncompressed
, but there are loads of examples of this in the stdlib and other packages. Thankfully with types it is really clear that the returned value is a boolean. Let me know if this doesn't address your concern.
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.
Approving it. Note that there are still a couple of things that can potentially be improved like #2323 (comment), https://github.com/stellar/go/pull/2323/files#r384694003, and https://github.com/stellar/go/pull/2323/files#r384679399. We can address some of them in other PRs tho.
PR Checklist
PR Structure
otherwise).
services/friendbot
, orall
ordoc
if the changes are broad or impact manypackages.
Thoroughness
.md
files, etc... affected by this change). Take a look in the
docs
folder for a given service,like this one.
Release planning
needed with deprecations, added features, breaking changes, and DB schema changes.
semver, or if it's mainly a patch change. The PR is targeted at the next
release branch if it's not a patch change.
What
Remove the
type
parameter stored alongside registered accounts and replace it with exposing information about which identities are set on an account to clients.Remove the
type
request and response parameters. Add theidentities
response parameter, and replaceowner_identities
andother_identities
withidentities.owner
andidentities.other
.Why
The
type
existed purely for clients to get some sense of what purpose an account was registered, but it's really meta data about how a client is using the service and isn't necessarily a core concept for theservice.
The value was also synonymous with which identities are configured for an account. A
type
ofpersonal
will always have only anowner
identity, and atype
ofshare
was always going to have another
identity alone or in addition toowner
.By removing the concept of
type
and instead just giving a client visibility into which identities are set on the account we reduce the number of concepts a client has to learn and know about which makes the API simpler, even if the change appears to make the API slightly more complex.The reason I replaced
owner_identities
andother_identities
is while thinking about the right way to expose the identities to the client it occurred to me the simplest method for a JavaScript client would be to have the identities be keys of an object, and so I structured the response that way, and it made sense to also modify the request to match.Known limitations
This is a breaking change to the API, but there are no consumers and the API is experimental.