-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add functions to automatically navigate device pages #135
Conversation
This serves as an example of how we could implement automatic page navigation, similar to what was done in `packngo`.
@@ -0,0 +1,58 @@ | |||
diff --git a/metal/v1/api_devices.go b/metal/v1/api_devices.go |
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.
If we were to maintain local copies of the Go templates, we could update the template files whenever we update the OpenAPITools version via the meta
CLI command which dumps the templates. In that case, is this where we would patch in a generic (mustache) version of the paginated executor:
We would need a mustache way to identify if pagination is supported in the resource, preferably without needing to modify the Java defined attributes.
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.
Finding a generic approach will be helpful for templating our generated Go pattern across Fabric, NE, and future Go SDKs.
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.
For Metal, if this is safe for unpaginated endpoints, perhaps we can always include ExecuteWithPagination
and it will degrade to a less efficient Execute
:
if page.Meta.GetLastPage() <= page.Meta.GetCurrentPage() {
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.
type Paginated interface {
GetCurrentPage() int32
GetLastPage() int32
}
type WithMeta interface {
HasMeta() bool // may just need this, if it exists
GetMeta() something // otherwise this
}
...
if meta, ok := page.Meta.(Paginated); meta != nil && ok {
// ^ check meta first? does meta always exist? nil? A WithMeta Interface check could be used if this simple check wouldn't suffice
}
index 2dc180a..5191167 100644 | ||
--- a/metal/v1/api_devices.go | ||
+++ b/metal/v1/api_devices.go | ||
@@ -2034,6 +2034,26 @@ func (r ApiFindOrganizationDevicesRequest) Execute() (*DeviceList, *http.Respons |
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 a significant patch context. Chasing func (r ApiFindOrganizationDevicesRequest) Execute()
will keep our patches applying safely. 👍
@displague @ctreatma
This was my template that would generate files like
{{>partial_header}}
package {{packageName}}
{{#operations}}
import (
"bytes"
"context"
"io"
"net/http"
"net/url"
{{#imports}} "{{import}}"
{{/imports}}
)
{{#operation}}
{{isPaginated}}
// The code is just a placeholder, I wanted to know if it's emitted only on paginated methods
func (a *{{{classname}}}Service) {{nickname}}Execute(r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}{{^isResponseFile}}*{{/isResponseFile}}{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}*http.Response, error) {
var items []{{returnType}}
pageNumber := int32(1)
// classname {{classname}}, {{&classname}}
for {
page, _, err := r.Page(pageNumber).Execute()
if err != nil {
return nil, err
}
items = append(items, page.Devices...)
if page.Meta.GetLastPage() <= page.Meta.GetCurrentPage() {
break
}
}
return items, nil
}
{{/isPaginated}}
{{/operation}}
{{/operations}} To consider the templates, we must have templateDir: /local/templates
files:
api_paginated_lister.mustache:
templateType: API
destinationFilename: _paginated_lister.go .. and |
I also tried to come up with an
.. but it's not completely correct. |
@t0mk The Path syntax is well defined, you can't add arbitrary fields unless they follow the |
@t0mk |
@displague Thanks for the tip on the As for the the plural, I think it can be worked out from the template variables. It might not be gramtatically correct, but I don't think it will conflict. |
Closing in favor of #150, which will generate the changes in this PR for all paginated endpoints using a combination of vendor extensions and custom templates. |
This PR adds logic for generating listing functions capable of going through all the pages (think devices in a project, or events in a device). It adds templates for the new code, docs, and code tests. The templates are fetched from oag v7.0.0, and then modified for the sake of the paginated listers. It uses vendor extension property object in the form ```yaml x-paginated: x-paginated-property: Events ``` The spec patching part can be done in other oag generated SDKs. related to #135 fixes #131 --------- Signed-off-by: Tomáš Karásek <t0mk@users.noreply.github.com> Co-authored-by: Marques Johansson <mjohansson@equinix.com>
This serves as an example of how we could implement automatic page navigation, similar to what was done in
packngo
.Relates to #131