-
Notifications
You must be signed in to change notification settings - Fork 327
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
control-plane: introduce a client for Konvoy REST API in the form of "remote" ResourceStore #73
Conversation
2c4bb11
to
92ef280
Compare
return m.Version | ||
} | ||
|
||
func NewStore(client http.Client, mapper rest.Mapper) store.ResourceStore { |
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.
Why do we need this Mapper
abstraction? Why just pass there WsDefinitions and use them internally.
Why this is an interface? What other implementation do you expect to see?
btw. Mapper
don't tell me much. What does it maps? How about ResourcePaths
. ResourcePaths.get(resource)
.
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.
WsDefinitions
is a server-side description of the API, rest.Mapper
is a client-side counterpart.
Between plain map[model.ResourceType]ResourceMapping
and func(model.ResourceType) (ResourceMapping, error)
I chose the latter to avoid inconsistent handling of missing types by client code.
And then it's a design principle to promote a function into a single method interface.
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.
WsDefinitions is a server-side description of the API
It's server side, but it's used for client anyways, just after one layer.
inconsistent handling of missing types by client code
where this incosistency can occur?
func(model.ResourceType) (ResourceMapping, error)
can be just a method of remoteStore
that uses the map.
I'm fine with this mapper, but please rename it to more descriptive name like ResourcePaths
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.
rest.Mapper
was renamed into rest.Api
return err | ||
} | ||
for _, ri := range rsr.ResourceList.Items { | ||
r := rs.NewItem() |
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 is question for the whole codebase. Why do we name the variables with such a short name?
I get that receiver s *remoteStore
is short, because it's used all the time (although I'd prefer this
, but this seems not to be go way...), but
rsr
, b
, ri
, r
? Why not listReceiver
, body
, listItem
, item
?
Sometimes is hard to follow and I need to go back to variable declaration to remember what was that.
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.
"idiomatic golang"
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 to be pragmatic. If convention hurts readability then it's maybe not the best one.
Clean code (descriptive names) can be applied no mater what is the languages. I'm not a fan of superLongNamedFromTheJavaWorld
, but I think there should be a middle ground somewhere.
if err := json.Unmarshal(b, &r.Meta); err != nil { | ||
return err | ||
} | ||
cr, err := newResource(model.ResourceType(r.Meta.Type)) |
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.
what does cr
stands for?
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.
core resource
ResourceRegistry: &model.SimpleResourceRegistry{ | ||
ResourceTypes: map[model.ResourceType]model.Resource{ | ||
(rs.GetItemType()): rs.NewItem(), | ||
}, |
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.
Why do we need a ResourceRegistry
with interface and impl if all we support is one type, that we already know. Why don't we just pass function to ResourceListReceiver for creating a new item.
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.
ResourceRegistry
is an interface for creating a new item of any supported type.
A function can always be wrapped into ResourceRegistry
(e.g., http.Handler
and http.HandlerFunc
).
I could replace in-place instantiation ( &model.SimpleResourceRegistry{ ... }
) with a factory method, e.g. SingleTypeRegistry(model.ResourceList)
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 understand what it is, but why do we need it? Why not just have
type ResourceListReceiver struct {
ResourceList
NewResource func() Resource
}
I think that Go code strives to be simpler without unnecessary abstractions which is common in Java.
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.
Changed to
type ResourceListReceiver struct {
ResourceList
NewResource func() Resource
}
92ef280
to
560a7fc
Compare
Context:
konvoyctl
must be able to request and unmarshal a list of resources fromKonvoy API Server
Changes:
model.ResourceRegistry
abstraction to instantiate a resource by itsResourceType
rest.ResourceListReceiver
type to unmarshal intorest.ResourceList
rest.Mapper
abstraction to describe REST representation of a resourceKonvoy API Server
in the form of "remote"ResourceStore