Standardize how we tell API endpoints to include sub-resources + remove functionality-specific custom endpoints
- Dominant language
- Clojure
- Stars
- 49.3k
- Forks
- 6.8k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 653
Description
We have a number of endpoints that return varying levels of details about sub-resources, for example `/api/table/:tableId/query_metadata`. It made a lot of sense to do that when the application was relatively small and had a limited number of endpoints like this, but as we've grown we've needed some combination of
1. adding more endpoints
2. use the existing endpoints but fetch more data than we need
3. make multiple requests to get all the data we need
These are some of the problems GraphQL solves, but if we don't want to implement GraphQL we could do a limited but REST-like version of it, which we kind of do in a couple places where you can include a parameters to tell the backend which sub-resources to include. For example `GET /api/database/` has an `include_tables` parameter.
Asana's API (and probably others) does this in a standard way with `fields` and `expand` parameters: https://asana.com/developers/documentation/getting-started/input-output-options
If we standardized on something like that, we could build in support to our frontend's "entities" system, so if you do something like:
```
Databases.load({ id: 1, expand: { tables: true } })
```
then later if you did:
```
Databases.load({ id: 1 })
```
we would know everything that's needed is already loaded.
Additionally, if we had a default set of properties for each object type (or full and "compact" like Asana does) that we load whether it's an individual resource (`/api/table/1`), list of resources (`/api/table`), or subresources (`/api/database?expand=tables`) then we could also know when don't actually need to make a request for `Tables.load({ id: 1 })` if it was previously loaded by `Tables.loadList()` or `Databases.load({ id: 1, expand: { tables: true } })`
(But again, this is similar to what GraphQL does, so maybe we should consider implementing GraphQL, and either have "entities" use GraphQL, or even replace "entities" with something like [Apollo client](https://github.com/apollographql/apollo-client))
Contributor guide
Research direction
Start with the listed API entry points, including /api/table/:tableId/query_metadata and GET /api/database/, then review how the frontend entities system handles Databases.load and Tables.load. Compare the proposed fields/expand approach with the linked Asana API and GraphQL references. Done would require an agreed standard for sub-resource inclusion, default or compact fields, and the relationship to GraphQL or entities.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure, graphql
- Domain
- api, backend-api-design, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 15/100