- Each resource requires a "type" (book, author, comment, etc)
- Each resource requires an ID (a unique identifier. must be a string or a number)
- Stored in context (or a context polyfill)
- Data is normalized by ID
- A location for By-ID lookup
- Support for an arbitrary number of ordered lists (supports server-side ordering, and any situation when the client needs an ordered list or grouping of resources)
- Support for client-side metadata for resources (could be used for forms, or if data is modified, or anything else that isn't normally persisted to a server)
- API to modify data in the state synchronously as well as asynchronously
- Uses window.fetch() under-the-hood
- Dedupes requests by default (configurable; using response.clone() to avoid multiple body reads)
- Supports per-object streaming (JSONS or gRPC-style streaming)
- Compatible with future fetcher (maybe a polyfill)
- Supports cancellation (or ignoring responses in browsers w.o. AbortController)
- Supports 4 cache policies (see Apollo or React Request docs for more):
- cache only
- network only
- cache-and-network
- cache-first
- Caches by a request key, which is generated by the inputs to the method (URL, serialized body, etc.)
- Supports multiple cache keys per request (to support JSON:API bulk ops and GraphQL)
- Inspired by/depends on future fetcher
- Generic enough to support different kinds of requests (gRPC calls, GraphQL subscriptions, HTTP2 streams, good ol HTTP1 calls)
- Provides hook to transform unstructured data to normalized format