-
-
Notifications
You must be signed in to change notification settings - Fork 849
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
feat: re-write get all routes to use pagination #1424
feat: re-write get all routes to use pagination #1424
Conversation
Pretty sure that's how it works. You can check if the parameters are being picked up by using the API Docs a :9000/docs. I was developing the Pagination stuff in isolation with the ultimate goal to replace the GetAll with the PaginationQuery, so eventually the GetAll would go away once it's not needed anymore.
What about attaching a method set to the PaginationBase model for class PaginationBase(GenericModel, Generic[DataT]):
total: int = 0
total_pages: int = 0
data: list[DataT]
next: Optional[str]
previous: Optional[str]
def set_next(self, route: str, query_params: dict[str, Any]) -> None:
if self.page >= self.total_pages:
self.next = None
query_params["page"] = self.page + 1
self.next = f"{route}?" + "&".join([f"{k}={v}" for k, v in query_params.items()])
def set_prev(self, route: str, query_params: dict[str, Any]) -> None:
if self.page <= 1:
self.previous = None
query_params["page"] = self.page - 1
self.next = f"{route}?" + "&".join([f"{k}={v}" for k, v in query_params.items()]) Then you could do the page calculation and just attach whatever other parameters came with the original request and it could be reused across implementation of the PaginationBase class. You could probably get the host/url from the Request object and then just use the defined Pydantic Model that is being used for the Query Parameters and pass that to the PaginationResponse as a dict before you return it, or just hard code it for the routes as needed. There's probably some edge cases we'd need to handle for list type queries, but that's what tests are for 😄 Hopefully that was helpful, and not just nonsense |
Ah yeah, that helps a bunch, thanks! That gives me enough to go on I think |
These commits replace the So it looks like this: {
"page": 1,
"per_page": 1,
"total": 6,
"total_pages": 7,
"data": [...],
"next": "/groups/shopping/lists?page=2&per_page=1&order_by=name&order_direction=asc",
"previous": null
} So it's up to the API consumer to append the route to the base URL. But you need the base URL stored somewhere anyway to connect to the API, so I feel like that's fine. Unrelated, it looks like I need to debug |
This is close to being done, there are still a few additional tasks (particularly tests). Some things we're going to want to address after this PR is completed:
|
I changed all of the frontend routes to support the paging route by hard-coding |
@hay-kot do you know why the postgres tests would be failing and not the sqlite tests? I'm trying to read the details but I'm lost. I'm not familiar enough with the differences between the two. Unsurprisingly the tests that are failing are the ones I had to tweak. |
Need to resolve the postgres test failures and create new test cases for pagination before this PR is complete/ready for review |
Should be ready now! Worth some extra attention to the frontend, though nothing should have changed |
Heyo! This looks EXCELLENT, thank you so much for all the work here. I'm working on getting this merged today, there's a few small changed I want to make.
I'm going to wrap up those small changes and try to get the TS errors to show up in CI so you might see a lot of traffic on this PR this afternoon... |
Thank you! Yeah good call on the Ah yeah the pipes are much easier to read, didn't realize that was new in 3.10. I'm excited to see this one merged! It unblocks a lot of optimizations, particularly the frontend sorting fun |
FYI I had to revert some changes you made to the headers in Basically it rendered the shopping list unusable. If you created a list and tried to add items it would never refetch because it would use the some built in browser caching to determine that it didn't need to make another request and would use it's last result. I'm not sure clear on all the details that caused it, but removing the route_class arg fixed it. Not sure how wide spread the issue is either. The Cookbooks at least seemed to work, but I didn't do a thorough check on everything that was changed. This should be ready to merge provided CI passes, then we can take another looking at the caching issue. |
Huh, that sucks. I haven't had any issues with the shopping list, but since it's cache related I can imagine there's a ton of variables there.
Awesome news!! |
Starting a draft since I'm expecting changes and a bunch of feedback. I haven't fully rolled out all the route changes yet, I've just started with shopping lists since I'm more familiar with those.
This feature aims to solve for task #1411: to implement the existing pagination logic in place of the ad-hoc get_all logic we're using today. I think this implementation is pretty straightforward, but I have a few things I'd like some feedback/help on.
I extended the
PaginationBase
per #1411, and I created aShoppingListPagination
schema using the base.General questions:
GetAll
schema correctly? I'm still new to some of these patterns and I kind of guessed on this one. TheGetAll
schema is being used in the route. I'm unsure what purpose it serves that thePaginationQuery
doesn't, but I see similar patterns on other routes so I'm probably missing something.next
andprevious
attributes. The logic is simple (if we're not on page 1, include the previous page; if there are more records to fetch, include the next page) but I'm not sure what the best way to generate the route URL is without reusing a ton of code. I thought about capturing the original route's URL and parsing/modifying the parameters, but I wanted to hear your thoughts before I implemented that.Next steps
GetAll
is being used correctlynext
andprevious
pages in the pagination responseremove oldrequires additional work to fully deprecate, out of the scope of this PRget_all
ad-hoc methodstotal_pages
calculation (see below)