-
Notifications
You must be signed in to change notification settings - Fork 898
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
Add paging links to the API #15148
Add paging links to the API #15148
Conversation
@miq-bot remove_label wip |
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.
@jntullo this is looking great! I just have some questions above. Feel free to 👖 if you need to discuss. Thanks!
lib/api/link_builder.rb
Outdated
@@ -0,0 +1,81 @@ | |||
module Api | |||
class LinkBuilder |
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.
Did you consider LinksBuilder
for this? I think this could better convey intent, since it returns a thing comprised of links
lib/api/link_builder.rb
Outdated
@@ -0,0 +1,81 @@ | |||
module Api | |||
class LinkBuilder | |||
PAGING_LINKS = [ |
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 think you want s/paging/pagination/ here
lib/api/link_builder.rb
Outdated
end | ||
|
||
def links | ||
PAGING_LINKS.each_with_object({}) do |link, object| |
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 do you think about expressing this as a literal (over metaprogramming) here? Something like:
{
:self => self,
:next => next,
# etc => etc
}.compact
lib/api/link_builder.rb
Outdated
format_href(prev_offset) | ||
end | ||
|
||
def self |
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.
Overriding self
here may have unintended consequences....perhaps self_link
?
lib/api/link_builder.rb
Outdated
end | ||
|
||
def paging_count | ||
@paging_count ||= subquery_count.nil? ? count : subquery_count |
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.
WDYT about the (slightly) shorter:
@paging_count ||= subquery_count || count
Jbuilder.new do |json| | ||
json.ignore_nil! | ||
[:name, :count, :subcount].each do |opt_name| |
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.
Does this disrupt the other caller of this method (expand_subcollection
) which still sends a :count
option?
lib/api/link_builder.rb
Outdated
:last | ||
].freeze | ||
|
||
attr_reader :offset, :limit, :href, :count, :subcount, :subquery_count |
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 couldn't find a consumer of the first reader - offset
, outside the class. WDYT about giving this and similar attributes private readers instead? I think this would help make the responsibilities of this class clearer
lib/api/link_builder.rb
Outdated
@limit = params["limit"].to_i if params["limit"] | ||
@href = href | ||
return unless counts | ||
@count = counts[:count] |
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.
Not necessary (but food for thought), the number of parameters needed by this object suggest that it might be helpful to Introduce Parameter Object
lib/api/link_builder.rb
Outdated
def previous | ||
return if offset.zero? | ||
prev_offset = offset - limit | ||
return if prev_offset < 0 |
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 seems to suggest that if I ask for page with limit 10, offset 5, I won't see a previous link showing the first five results. I think I'd expect to see a link (expressing limit 10, offset -5) though I'm not sure if that makes sense. @AllenBW any thoughts?
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.
hm yeah, this is a tough one. I guess I was just thinking first would cover this case, but perhaps they don't want that. Thoughts @AllenBW ?
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.
UGGGHHHH sorry for the delayed response to this, it totally didn't hit my 📻
showing all links no matter what offset would be besssssssst. the example case being... lets say you wanta make a list of the different pages (say 1
to 10
) and when you click a number you see that cut of results, if we start with 5
we would wanta also be able to checkout 4
, 3
, etc etc
when ya say, @jntullo first would cover this case, watcha mean?
again so many apologies for my late reply here :( here have an I'm sorry 🌮
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.
@AllenBW with the first link, the offset would be 0, at which point you'd be able to see 0..5
. But I could see the case for wanting to continue with that same offset
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.
OOOOOO so collection of ten limit of 2 offset of 6, would you have links for offset of 4, 2 and 0? @jntullo
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.
No, you would get previous
which would be offset of 4, you would get first, which would be offset of 0, you'd get next which would be offset of 8
lib/api/link_builder.rb
Outdated
attr_reader :offset, :limit, :href, :count, :subcount, :subquery_count | ||
|
||
def initialize(params, href, counts) | ||
@offset = params["offset"].to_i if params["offset"] |
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.
Do you need to pass in the params
if you have what you need in the href arg, and that url needs to be parsed/rebuilt as part of this logic anyway?
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.
@imtayadeway not a bad suggestion, the only reason why I am not entirely sold on it is the rebuilding part is a bit simpler than the parsing part, and if we already have those parameters, I would prefer to just use those rather than re-parsing it. If that makes sense? Open to discuss though.
@jntullo bump |
This pull request is not mergeable. Please rebase and repush. |
|
||
Rbac.filtered(res, options) | ||
def subquery_search(res, options) |
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.
not clear offhand what subquery_search does (as called from 179 if miq_expression.present), might need a better name
lib/api/links_builder.rb
Outdated
@limit = params["limit"].to_i if params["limit"] | ||
@href = href | ||
return unless counts | ||
@counts = counts |
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.
maybe replace above 2 lines with
@counts = counts if counts
lib/api/links_builder.rb
Outdated
def last_href | ||
return if (offset + limit) >= paging_count | ||
last_offset = paging_count - (paging_count % limit) | ||
format_href(last_offset) |
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.
while I can see us skipping previous and next (i.e you're in the first page already or you're in the last so no need to paginate further), I think we should always return the self, first and last href's.
This is really nice @jntullo
|
have the link builder take in the count parameters
update specs to be more descriptive;
Thanks @jntullo for updating this PR. LGTM!! 😍 /cc @imtayadeway does this look good to you ? you have the X in the reviewers section. |
rubocop fix
Checked commits jntullo/manageiq@f10ea5a~...c4d59f6 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 app/controllers/api/base_controller/renderer.rb
|
Looks like the rubocop.yml was updated - there are a lot of those errors throughout renderer, will fix all of them separately. |
This adds paging links / page count in the following format if both
limit
andoffset
are specified in the GET request:If there is no previous (ie you are on first), there will be no previous link. This holds true for the other cases such as being on the last, etc.
Things still working on:
@miq-bot add_label api, enhancement, wip
@miq-bot assign @abellotti
cc: @imtayadeway