# Data access  There are three ways to interact with your data in your Gadget apps: * : Read and write data, and run custom business logic. * : Read-only fields on models that can transform data, and aggregate data across relationships. * : Read-only queries capable of running complex data computations and aggregations. ## API access  Gadget automatically generates and documents **GraphQL** CRUD (create, read, update, delete) APIs for your application as you add, update, and delete [models](https://docs.gadget.dev/guides/models). You can extend this API by adding custom [actions](https://docs.gadget.dev/guides/actions). A Node.js API client is also generated and used to makes requests with **JavaScript** or **TypeScript**. **React** hooks built by the Gadget team can be used to read and write data from your frontend. Use the API for most CRUD operations and any actions that require business logic. [Learn more about using the API to access data](https://docs.gadget.dev/guides/data-access/api). ## Computed fields  [Computed fields](https://docs.gadget.dev/guides/data-access/computed-fields) are predefined, read-only stored as fields in your model. They are used for common computations, like calculating a customer's total spend or counting the number of related records. Example of a computed field query: ```gelly // in a computed field with the sum of a customer's orders field on customer { sum(orders.totalPrice) } ``` Computed fields are fast and available like any other field in your API for easy access: ```typescript const result = await api.customer.findFirst({ select: { totalSpend: true, }, }); ``` [Read more about computed fields](https://docs.gadget.dev/guides/data-access/computed-fields). ## Computed views  [Computed views](https://docs.gadget.dev/guides/data-access/computed-views) are complex, read-only that allow you to perform aggregations, filtering, and transformations on a large dataset, across multiple models and/or relationships. They are useful for creating reports, dashboards, or any other complex queries that need to aggregate and manipulate data across models. Example of a computed view: ```gelly // in a computed view for top 10 products ordered by total sales view topProducts { products { name totalSales: sum(orders.totalPrice) [order by totalSales desc limit 10] } } ``` Computed views are callable from your API and can be predefined or called inline using your API client. Using `api.view()` for inline views allows for dynamic query construction. ```typescript // a predefined computed view, called using the API client const result = await api.product.topProducts(); // an the same computed view with a dynamic limit, called inline with api.view() const result2 = await api.view(`{ products { name totalSales: sum(orders.totalPrice) [order by totalSales desc limit ${limit}] } `); ``` [Read more about computed views](https://docs.gadget.dev/guides/data-access/computed-views). ## Gelly  **Gelly** is Gadget's data access language designed to handle complex computations and aggregations that are difficult to execute performantly with the public API. Similar to SQL, Gelly excels at computations across large volumes of data. Gelly queries are declarative, enabling Gadget to precompute or re-compute values efficiently, which is why Gelly is used for both computed fields and computed views. [Learn more about Gelly](https://docs.gadget.dev/guides/data-access/gelly). ## What should I use?  Each of the tools available in Gadget is designed for specific scenarios. Here's when you should use each: * **API access**: Standard CRUD operations and running custom business logic. * **Computed fields**: Common calculations relating to a single model record. * **Computed views**: Complex queries involving multiple data models, aggregations, and transformations.