Gadget automatically generates and documents API endpoints that allow you to interact with your data. The API is how you fetch information for arbitrary queries (e.g. a query that is powered by the user's input on the frontend) or simple, predefined queries. For handling data in aggregates, or complex predefined queries, we recommend using computed fields.
Each time you add a new model to your project, Gadget instantly generates a public and private API to interact with the records stored in that table:
The public API is how your production application runs its business logic. The public API is described in actions that run both the database work we want our backend to do, along with any additional logic you specify. For example, a blog might have a createBlog action that persists blog data to the Gadget database before running a function to send a success email to the author.
The internal API is how you quickly interact with data (create, read, update, delete) at the database level, without running any additional business logic.
Your production application's frontend will typically make API calls to your Gadget backend via your public API, whereas your project's internal API is primarily used to fetch information to run the server side functions that power your actions.
While, computed fields are typically the recommended approach to handling predefined aggregate queries (e.g. counts and sums) in Gadget, they cannot take in dynamic filters. In the event that your app has a query that requires dynamic filtering, you will need to aggregate the information you need at read-time by paginating, and produce your own filtered sums and counts.
To produce read-time aggregates with dynamic filtering, you can fetch the desired records and paginate through them to get the desired aggregate data. This allows you to apply any filters you want to the GraphQL query and ensures you get an accurate count. The downside to paginating through all records is performance - the maximum page size in Gadget is 250 records; if the total count is 100000 records, walking through them in increments of 250 will take a long time.
When to paginate
- You are confident that you won't have a large number of total records in your collection
- You have dynamic filtering options that don't allow for counts to be pre-calculated
When to avoid pagination
- You may need to count a large number of records
- You don't need dynamic options for filtering your counts
For instance, if you want to get the count of all products in a Shopify store:
Within Gadget it is highly recommended to use computed fields in most instances, however, there are a few cases where you can consider pre-aggregating data at write time.
Large datasets: Pre-aggregation is particularly beneficial when dealing with large datasets where performing aggregations or complex calculations on the fly can be computationally expensive.
Grouping data: As Gadget doesn't currently support computed views (yet), there are cases where you might need to group data. In these instances, using pre-aggregation strategies with a combination of computed fields will be necessary.