Description:
I have a seeProfile resolver, which gives back a profile of a particular user.
This user has a photos array and I want to paginate these photos and I can't figure out how. I have a workaround but I'd like to know a way - shall it exist - to paginate a field of this one user.
Workaround:
I can simply make a resolver for fetching pictures for a particular user with .findMany() and paginate them with take: and skip: . But then I make two queries instead of one. So, if anyone knows a way to paginate the photos inside findUnique query, please let me know, thanks!
Unfortunately, there's no way as of now to implement pagination inside the include relation in Prisma.
You will have to make two separate queries with Prisma, as you described in your workaround:
One findUnique query to fetch the user records.
One findMany query to fetch the approrpriate photo records.
I can simply make a resolver for fetching pictures for a particular user.
Perhaps it just makes sense to do both queries in the same resolver, to avoid two requests to the API.
Related
Background
Let us consider a hypothetical scenario. Suppose we have five different tables in our database,
Customers
Categories
Products
Orders
OderDetails
Our client wants us to add a search bar to the frontend, where a user can search for a specific product and upon tapping the search button, matching products has to be displayed on the frontend.
My Approach for Tackling This Problem
In order to add the aforementioned functionality, I came across the following strategy.
π I would add an input box to ender the product name and a submit button.
π Upon pressing the submit button, a GET request will be sent to the backend. On the query parameters, the product name that has been entered by the user will be included
π Once the GET request is received to the backend, I will pass it down to the ProductsController and from within a method defined inside the ProductController, I will use the Product model to query the products table to see if there are any matching results.
π If there are any matching results, I will send them to the frontend inside a JSON object and if there aren't any matching results, I will set a success flag to false inside the JSON object and send it to the frontend
π In the frontend, if there are any matching results, I will display them on the screen. Else, I will display "No Results Found!"
Problem with My Approach
Everything works fine if we only want to search the products table. But what if, later our client tells us something like "Remember that search functionality you added for the products? I thought that functionality should be added to orders as well. I think as the list of orders by a user grows and grows, they should be able to search for their previous orders too."
π Now, since in our previous approach to search products was implemented in the ProductController using the Product model, when we are adding the same functionality to Orders, WE WOULD HAVE TO DO THE SAME THINGS WE DID IN THE ProductsController AGAIN INSIDE THE OrdersController USING THE Order model. It does not take seconds to understand that this leads to duplication of code.
Problem Summary
β How do we add an API endpoint in laravel for a search functionality that can be used to search any table in our database and get results, instead of the search functionality being scoped to a specific controller and a corresponding model?
A good start would be to create a trait called something like searchable and add it to all the models you want to search and put any shared logic between the different models in there. Possibly you'd want to manually allow different columns so in each model you have an array of searchable columns which you'd refer to in your trait.
Your controller would have to point to the related model and call a method in the trait that searches.
As others have pointed out this is a high level question so I won't go too much in detail. Of course there are a million ways to implement this, just try and keep shared logic in place.
My app uses AppSync resolvers to fetch data from DDB and return it to our front-end. One table we have is for Notifications. A Notification can be either pending or default (non-pending). The table itself has a primary key of notification_id and we have a GSI called userIndex to grab the notifications for a user, with a sort key of timestamp.
In the app, I show all notifications in a list, pending first and then default. Given that a user may have many notifications, I'd like to implement pagination to fetch a batch at a time. The only way I've been able to do this is to
change the query to include a isPending parameter, which I use as a filter expression for the query to only return notifications that are isPending or isNotPending.
Store two "nextTokens", one for each isPending and isNotPending, along with corresponding lists.
Make separate queries for pending/non-pending, and use the filter to return to the appropriate list.
This is obviously inefficient and I am re-reading data from DynamoDB. My question is, given my DynamoDB table/requirements, is there a way I can paginate so that I can get all the pending notifications first (sorted by timestamp) and then all the default notifications next (sorted by timestamp) by using one query and one nextToken
I've seen the use of #model and #key, but I haven't been able to make it work in my app.
Thanks!
No, not really. There is a hard limit on returns for a Dynamodb query - and that cannot be bypassed. the only way to make use of nextToken is another query.
However, it is also worth noting that the FilterExpression happens after the data has already been retrieved and is filtered client side. It does not reduce the documents pulled from the query - only whats displayed. So the next token is still going to be (relatively) the same for each query. You can instead filter it yourself after the call before the next pagination query and save yourself a little bit in terms of multiple calls.
Is there a way to convert a pagination to a collection/array to get all items like:
Users::where(...)->paginate(15); //paginated
Output: 15 per page
Users::where(..)->get(); //not paginated
Output: all Users per page
So i is it possible to do something like that:
Users::where(...)->paginate(15)->removePagination();
Wanted output: all Users per page
You have 2 choices:
either retrieve the complete query result by chaining ->get()onto your query.
call ->paginate() to retrieve a pagination instance, which automatically retrieves the first page, and it automatically links the example.com?page=1 url param.
(there are also some other functions that complete the query like ->pluck() or ->value() which might not be applicable to you)
As far as I'm aware you cannot revert to the complete collection instance when you have the pagination retrieved (\Illuminate\Contracts\Pagination\LengthAwarePaginator), nor does it make sense to do so since the idea is to retrieve as little data as possible such that your application stays fast.
Maybe you should explain what you're trying to do; for instance you can retrieve the total count in the paginator using SomeModel::query()->paginate()->total(), among other things. You might not need the complete query after all.
Curious if I constructed and tracked this m2m relationship correctly. Seems strange that every object in those arrays are named "user": {...} or "pip": {...}
Seems like these both should work
Update with screenshots:
Users table relationships:
Pips table relationships:
There's currently no automatic way to "hide" the join table from the GraphQL query and response. You need to traverse through the join table to get back the results you want from both directions so you can't avoid it using the default generated API.
It is possible to extend the GraphQL API using SQL Views if you want to try and "flatten" things from the perspective of people consuming this data.
Alternatively, I'd recommend calling the relationship something different to make it obvious that you're navigating through a join table. I'd recommend actually calling the relationship user_pips instead of pips as it makes it more clear what you're actually retrieving.
I have created two content type builder which are category and sub-category respectively. While adding sub-category I had define one relationship which is one-to-many.
After creating successfully, I found that the basic CRUD API has been created and it works fine.
Now I need to find data like if I pass category-id then it has to return me it's all sub-category list.
Well, for this I can also write API manually, But I thought that strapi provides a feature of relationship though it may have some way to fetch data from the relationship table. In my app, I had set up a project with MySQL.
Expected output: Need a way to fetch data from a relation without writing custom API. Looking for inbuilt feature of strapi.
You have to use deep filtering.
πHere is the documentation https://strapi.io/documentation/3.0.0-beta.x/guides/filters.html#deep-filtering
So you will be able to do /categories?sub-category.id=[your id]