Changes between Initial Version and Version 11 of Ticket #6981


Ignore:
Timestamp:
Jul 2, 2008, 1:39:43 AM (11 years ago)
Author:
kriszyp
Comment:

Replying to guest:

okay, so this is not a "bug". but this is what i mean by pluggable, and in my earlier conversations about a violation of separation of concerns. Perhaps it is just my quirky way of thinking, but I think that a more layered approach would make for a cleaner, more extensible code, especially for a toolkit where it is fully expected people will be extending the code.

Absolutely, but I thought I actually had a very layered approach, more layers than you have suggested with your design. My layers include: Store API for services dojo - dojox.data.ServiceStore? Store API for read-write (REST) services - dojox.data.JsonRestStore? Rest Service - dojxo.rpc.Rest Index/referencing resolution - dojox.json.ref SMD Service creation - dojox.rpc.Service Multi-store/table manager - dojox.rpc.JsonRest? Offline capability - dojox.rpc.OfflineRest? Comet/live-sync capability - dojox.cometd.HttpChannels?

I think there are at least a few different layers that *should* be present and interchangeable (pluggable)

Absolutely, although of course with many development exercises, we would like to keep components as distinct as possible, but meaningful and efficient interaction often requires signification interaction.

  1. persistence -- this is the CRUD functions. I should be able to use an RPC service, a custom class, whatever. I just agree to implement the CRUD api which would be very simple. (I think this will allow you to plug REST, RPC, etc in very easily. Or imagine a person who build a GWT-RPC service and now wants to convert to to dojo without changing the service. Build a little CRUD that communicates withy GWT-RPC servlets and you are done. An additional benefit may be offline storage. Build a CRUD connector to Gears, and the rest of your code is unchanged).

Right, we have pluggable services. But, ss discussed earlier this requires levels of integration to achieve efficient cross-site referencing with prototyping.

  1. caching/instantiation/query -- this is the piece that uses the raw data from the persistence layer, and creates the appropriate representation on the client. This is what I have been referring to as an "EntityManager?".

This is what dojox.json.ref does. This is more modular than "EntityManager?", because the handling of transactions between stores is separated into a separate module.

  1. client side querying mechanism -- this could potentially be completely independent of the caching layer, and could allow for different client-side query implementations (for example, a simple dojo.data.filter/sorter based one, perhaps a TaffyDB based one?) This would connect to the EntityManager? in some way

This doesn't exist yet, this is what we have been discussing, and doing it in a new module is fine.

  1. Store API -- Read/Write/Identity? etc. that provides store-per-class granularity. This would be "managed" (either explicitly or transparently) by the EntityManager? (so that cross-store references and object identity could be maintained).

JsonRestStore? provides the Store API.

The current implementation of JsonRestStore? has all these concepts, but not in the distinct layers as best as I can understand. The obvious case in point is that dojo.rpc.Rest actually handles instantiation of objects, when I think it should really only deal with "raw" data and how to connect to get/put/post/delete methods the right way.

If the Rest service doesn't handle object instantiation than you actually lose more modularity than you gain. You could no longer use dojox.rpc.Rest directly, since it would return different objects than would appear dojox.data.JsonRestStore?. Indexing and referencing should not be so tied to the data store. In the interest of modularity I want indexing and referencing to be separated from the data store. On the otherhand index/cache is direct concern of Rest, that is foundation of the Rest concept. Now it may be worth looking at house the Rest service could be broken into separate modules, a high level Rest handler and lower level transport handler. I would definitely consider that.

I could see a JsonRest? class that would assume the return types from the get/put/post/delete methods were Json objects (since they could theoretically be anything from raw text to csv to whatever, right?)

JsonRest? really wouldn't do anything other than guarantee that your return results were the appropriate raw json (i.e. it could handle conversion from other formats if needed/desired)

I could see ServiceStore? being the real meat of an EntityManager?. It would be abstract and require subclasses to "_processResults" as it does now -- and this is where the instantiation of the objects from whatever raw CRUD service data would occur.

ServiceStore? works fine on it's own, why would I treat it as abstact?

Client side queries are really not yet described.

Right, we are discussing that one.

And then JsonServiceStore? would be a very specific implementation of a ServiceStore?. There actually would not be a lot of code here. It could take any CRUD that promised to meet the CRUD api AND return Json. (A Rest, JsonRest?, or any other CRUD implementor). its only real purpose in life would be to implement _processResults, which it would do using the dojox.json.ref.resolveJson mechanism.

Once again, we are losing modularity if we tie data stores to dojox.json.ref.

Finally, you could create a JsonRestStore? that essentially offers "shortcuts", so you don't actually have to create a JsonRest? service, but instead just provide the "target", etc directly to JsonRestStore?.

You can already do that, you can provide a target to JsonRestStore? and it will work. That is actually how I would recommend using it.

Do you see what I mean about how the current implementation, while it has "layers", there is a lot of bleeding between the layers?

Hopefully I have addressed the need for certain interaction (bleeding) between layers, hopefully we can improve areas where we can improve modularity.

Now, I understand this is JS and not Java, and its not pure OO, and maybe having all these layers is a performance nightmare. But I don't think it has to be.

Performance has been a very high priority. This is also one of the reasons that object instantiation takes place in dojox.json.ref, so the indexing and object instantiation can take place in one sweep.

If a layered approach like this were taken, and then someone like me came along and wanted to build my own service, but really just because i didn't like Json-Schema (which, is not the case, by the way) and wanted to use a different method for instantiation, or even just skipped the whole instantiation phase and used the raw objects, i could. With the current implementation -- as proven by the example above, I can't swap out one layer and roll-my-own service and still get a lot of the benefit of the work you have already put in.

Right, that is definitely the idea, and I appreciate your help in polishing in towards that end.

Here is another example. Lets talk about the API layer. The usual implementation of this could be quite simple, wrapping ServiceStore? calls for specific stores. But now lets say I want to extend the API to support dot-path'd attribute (e.g. store.getValue(item, "person.name.firstName")), in a layered system, I would not have to do more than extend the Api layer, mix back in all the existing other classes, and suddenly I've got a working solution for my needs.

We using JavaScript?, that is easy, you don't need my help for that :).

Obviously I could hack the current solution and make it work for me. And as you know, I've already created a solution that works for me that is a bit more layered. But I would like to see dojo -- as a platform for development and infinite extension and possibilities -- try to be as arhcitecturally disciplined as possible, to really facilitate that kind of use.

Hopefully I have clarified the modular architecture I am using. It sounds like dojox.rpc.Rest is the area that may need more work (and adding client side querying)

I hope that makes some sense. You all have a LOT more experience than I do in these matters, ESPECIALLY on the client-side, but I just want to be sure this issue is really thought through.

Certainly appreciated!

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #6981

    • Property Owner changed from Jared Jurkiewicz to kriszyp
    • Property Status changed from new to assigned
  • Ticket #6981 – Description

    initial v11  
    11I know JsonRestStore is not even out yet... but here is a thought. While I understand that REST is based on the POST/GET/PUT/DELETE for CRUD, JsonRestStore is by far the most robust RPC based store built yet. I want to use it for all my CRUD-requiring data access, but my server blocks PUT and DELETE. So, I know its slightly less efficient (maybe), but how about supporting exactly the same envelope as REST for the service, but only using GET and POST and then adding an "action" attribute to the query-string of "POST/PUT/DELETE".
     2
    23
    34I've actually "subclassed" dojox.rpc.Rest, but I think in a very volatile way that will likely break as the implementation of JsonRestStore and dojox.rpc.Rest get more mature. But this works for me for now, and I perhaps a more formal support for this can be added in the future.