JsonRestStore retires MedryxORM
When I was first designing the MedryxORM, I had a need for a data store that could perform advanced functions that no store in Dojo 1.1 had available. However with the addition and significant improvement of dojox.data.JsonRestStore, I am happy to say, that I think, after only one month, I can safely retire MedryxORM. This is a good thing. I always opt for off-the-shelf over custom solutions. And, you get the whole dojo communtiy supporting you when you use an official dojo.data store.
In the last month, I’ve worked with Kris Zyp — the Json guru at Dojo — and I really think the JsonRestStore has come a long way to solving many problems with complicated client side data management. First off, let me make this very clear — despite its name, JsonRestStore does not require you to use a RESTful data source or web service. Any web service will do — RPC, or home-grown. You just plug in your services into the JsonRestStore, and the store handles the rest. I actually think its name is its biggest flaw. Perhaps it should simply be JsonStore, so that more people would use it… but I digress.
So here are the features of JsonRestStore that have allowed my to say goodbye to the EntityManager and MedryxORM:
- Unique Object Identity: One of my requirements was that if the server sent down an entity, I wanted to be sure that however I accessed that entity, that I got the same entity. So whether I used store.getValue() or item.foo, or item.getFoo(), or item.getBar().getFoo(), I always want the same entity. In my design, there was therefore one store that handled all kinds of entities. This proved a bit clunky, because to access anything from the store via fetch, you had to provide an “entityClass”. JsonRestStore accomplishes this same goal without the clunkiness. With JsonRestStore you create one store for each entityClass. Behind the scenes, JsonRestStore uses dojox.rpc.JsonRest to be sure object identity is maintained. This means that you need a store for each entityClass, but that makes it crystal clear what you are querying for when you do a fetch. Overall, a better design IMHO.
- Conversion of JSON hashes to first-class JS objects, allowing for custom functions and business logic to be implemented within entities: If I have an entity, I want to, for example be able to create a toString() method on it, and each time an entity of that type created, it should inherit the toString(). The server should not worry about javascript methods, so sending it in the native JSON data is not the right solution for lots of reasons. My EntityManager used the “class metadata” to determine the class of information being retrieved from the server, and instantiating each object from the metadata, and then mixing in the server data into the object instance. JsonRestStore has a similar “class metadata” concept, but it is more standardized — and based on JsonSchema. If you provide a schema, and it has “prototype” property, then any methods/fields in the prototype are used when the entity is instantiated. Since standardization is a good thing, and since JsonSchema is emerging in the JS world as a standard, I think this is probably a better approach than the custom metadata that was created for MedryxORM — despite the fact that it was loosely based on EJB3/Hibernate.
- Built-in laziness: Use store.getValue() and you lazy load items for free. There is a little bit of learning on how to handle laziness on the server side, but its pretty straightforward (and I hope to write a post about it soon).
- Client side filtering/sorting: JsonRestStore allows you to cache query results on the client and then filter them and sort them seamlessly on the client. This safely retires my “named queries”, and is both more efficient and more extensible.
Honestly, the only thing missing from JsonRestStore is de-novo support for javabean style getters and setters that also give you free laziness, and support for dot-path notation in getValue(). I’ve added this with a simple additional class called BeanStore that extends JsonRestStore, and I have submitted BeanStore to Dojo to see if they think it is broadly applicable enough to include in dojox.data. We’ll see.
I have to say, the most irritating part of all of this is that I lose 2 weeks of work. But I can always look back at how intricately I now understand dojo.data and JsonRestStore and know the time was not completely wasted. In my next post, I hope to share with you my understanding of JsonRestStore and its use.