Documentation
dojo.store¶
PROPOSAL
Authors: | Kris Zyp |
---|---|
Project owner: | Kris Zyp |
Available: | coming with V1.6 |
Contents
Dojo Store is an uniform interface for the access and manipulation of stored data. Dojo Store is intended to supercede, integrate, and improve upon the Dojo Data API and Dojo Storage API with a simple, easy to implement and extend API, based on HTML5/W3C’s IndexedDB object store API.
Design Goals¶
- We want to make it very easy to for people to implement their own object stores, essentially one should easily be able to write something up handle the communication to their server without having to deal with much more than writing the XHR calls. Higher level functionality can be built on this. A key to this strategy is a very simple API, that requires a minimal amount of required complexity to implement.
- We want to maintain the same level of functionality that Dojo Data provided. While there will be very little (if any) core parts of the object store API that MUST be implemented, there will numerous parts that can be implemented to incrementally add functionality. Optional functionality will be determined through feature detection (checking to see if a method exists). As I noted in the meeting, having lots of optional features does shift some complexity from the store implementors to the anyone who wishes to use stores in a completely generic fashion. However, I believe that our widgets are the primary generic store users, and that most application developers are working with a known store, with a known set of implemented features. In particular, if they know they are using a sync store, the interaction with the store becomes extremely simple. For now I will suggest that basically every method is optional, and the presence of the method indicates support for that feature. However, practically one would at least need to implement get and query, a store without read capabilities is pretty useless, but that should be self-evident.
- Every method can be implemented sync or async. The interface is the exactly the same for sync and async except that async returns promises/deferreds instead of plain values. The interface requires no other knowledge of specific callbacks to operate.
- Objects returned from the data store (via query or get) should be plain JavaScript objects whose properties can be typically accessed and modified through standard property access.
Dojo Store API¶
Properties¶
Property | Type | Description |
---|---|---|
idProperty | String | Name of the property to use as the identifier |
data | Array of Objects | If the store has a collection of cached objects, it can make this available in this property. This is included so an additional layer could add referential integrity cleanup on object deletion (which is a pain to implement). |
Methods¶
Every method in the API is optional, it’s presence indicating support for that feature. Every method can return a promise (except where noted otherwise) to represent an asynchronous completion of the action. (Some of these are still wavering a bit in W3C’s object store API):
How is about a dojo.store.clear() method?
Will clear all the (cached) objects of the store.
Result Sets¶
Objects returned from store should primarily be treated as normal hash objects and have standard JavaScript properties to access their data and modify their data. However, the following methods are defined as possible methods that may also be available on the objects returned by the store (once again, they are optional). These methods should ‘’‘not’‘’ be the object’s own properties (hasOwnProperty(methodName) should return false), but rather should be inherited from one of the object’s prototypes). This is to ensure ease of enumeration of data properties. Once again, all of these methods are optional, and all may return promises if the operation will be performed asynchronously:
Subscriptions/Watches on Result Sets¶
One can subscribe to changes in data through the subscribe method on the result set (the object returned from a query). The subscribe method has the following signature:
[Rationale: The purpose of using this style of notifications (instead of the Dojo Data notification style of events on the store) is to deal with several problems I have seen with Dojo Data notifications. First, it neglects that fact that most of the time users only want to listen to events from the queried subset of the items in the store, and that subscriptions can be costly. While subscriptions are usually cheap on the client side, carte blance subscriptions can actually be very expensive on the server side (with Comet-style notifications), forcing the server to send excessive events and then forcing the client to filter them.
Also this subscription deals with an issue we have experience with Dojo Data in that often new items and item changes can affect query results in ways that the widget can not understand because the queries are opaque to the widget. With the grid, all onNew items result in an addition of a row, regardless of whether the new item actually matches the query. The grid itself knows nothing (and should know nothing) of how queries work, and so it can’t filter these events. By putting notifications on the query action itself, notifications can be stated in terms of how they affect a given query result set, which is what the widget ultimately cares about.
I have intentionally used different event names to be clear that the semantics are different than the Dojo Data notifications. The distinctive events are defined by how they affect the query result set (not whether they have come into or gone out of existence by some definition of existence). Also, the onUpdate applies to an entire object, not per property modifications.
It also may be worth considering adding the notification events to an options parameter for get(id) calls.
We will need to include a helper mixin or wrapper to make it easy to implement the query function.]
I believe this generally facilitates all of the Dojo Data functionality. Some of it may require some composition, but I think most of the needed things would be in place to achieve anything you could with Dojo Data. The one thing I did intentionally omit was getLabel/getLabelAttributes, as I think is clearly a UI concern. It would be easy enough to include a labelProperty property on the store, but I don’t think it is necessary.
Core Functionality to be Shipped with Dojo¶
Having an interface/API is not enough, we want to ship good out-of-the-box object stores that developers can readily utilize for common use cases and easily extend and customize. We also need good modular components for building stores. We could have the following two core stores based on the typical pattern of in-memory and server-based data stores:
dojo.store.Memory
An in-memory object store that queries, modifies, and accesses client-side in-memory data. This would fulfill the conceptual role of ItemFileReadStore/ItemFileWriteStore
dojo.store.JsonRest
An server-oriented JSON/REST object store that queries, modifies, and accesses data through RESTful HTTP requests. This would fulfill the conceptual role of JsonRestStore/QueryReadStore/ServiceStore.
We should also move in the direction of providing composable functionality by providing store “wrappers” or store “middleware” that takes a store and add functionality. A couple key store wrappers:
dojo.store.Cache
Adds caching capability to the store. This eliminates the need for a base store to deal with caching concerns.
dojo.store.JsonSchema
Handles validation of data through JSON Schema as well object referencing through JSON Schema’s link definitions.
With this one could easily mix and match wrappers and base stores to achieve various types of functionality.
Another utility module would be a query helper.