Skip to main content

Constraint-Based Services with RPC

Posted by jhook on April 12, 2006 at 3:59 PM PDT

The Concept

A while back, I started to write DAO's for an application at work; and of course we chose Hibernate. I've been on this 'K.I.S.S My App' kick lately with keeping things as simple as possible and actually leveraging APIs to their full extent. This theme was carried out so much so that the DAOs actually returned Criteria objects:

public class WidgetDao extends DaoService {

  public Criteria queryByCategory(long catId) {
    return this.getSession().createCriteria(Widget.class)
                  .add(Restrictions.eq("category.id",  catId);
  }

  public List findByCategory(long catId) {
    return this.queryByCategory(catId).list();
  }
}

So why the heck would I expose Criteria objects? Well, the answer is simple: I wanted to allow the most flexability at the point of most concern. So the DAOs expose this initial constraint over the data with whatever business/domain logic (the case above is really simple), but as to the what and how the data is returned, now the client of the DAO is free to decide.

This really came to light when creating UIs where we could gain Criteria instances, then assign projections, sorting, and additional filtering over the data without pressing this use case back onto my DAO/Services layer. The end result was highly efficient, agile, and fast data mining within the UI. No needless layers of complexity and procedural contracts with my service layers to expose the information I needed.

SOA, RPC, and AJAX

Let's apply this concept to SOA and RPC. Many of these new AJAX 'frameworks', and Action MVC frameworks in general, rely on pushing content around. You spend time building up these procedural contracts to expose data models, but there's no way to know what information is used and how the information will be used.

This blindness really comes to light when you are dealing with desparate systems with client/server or server/server architectures. You've written an RPC method to deliver a set of Widgets. Well, in your domain, Widgets have a lot of aggregate and composite relationships, how do you know what to expose and how to expose it to all clients? You may simply choose to push 2K of object graphs when all you needed was the Widget's ID and Description. So you begin to see the waste. This gets even more tricky when clients access to some of that aggregate data on Widgets, and if that fails in performance, are you going to write more RPC methods?

Some of the public SOA APIs from major vendors kind of do this with providing specialized parameters/attributes within their requests to specify client-based constraints such as, "Do you want short or long details on the product search?" (Amazon).

Possible Solution

Because we are blind to all possible use cases of our domain models and services, we come up with a way for the client to interrogate the data or add constraints to our RPC calls within the remote request itself. Ideally, this would be taken care of by some mediator framework such that the RPC could be invoked on the server, but based on the constraints provided by the client, we can selectively return "lighter" responses.

So take a Widget catalog exposed over SOA. We still have the RPC contract for security such that we apply initial constraints, but client could use XQuery or some other standard to specify how and what is being transported back over the network. How do you know all the possible ways of exposing your data model to a client? Wouldn't it be easier to just use some kind of mediator to query/filter/sort your data as each client needs it?

In terms of the UI, it would be conceivable to back this by a templating engine on the client such that a JavaScript Agent could pre-determine what data is presented and selectively query generic RPC services on the server.

Conclusion

It all comes down to a cost highlighted with network latency. Having objects in memory on the server is cheap, but we all know that XML/etc is horrible at efficiently representing object graphs and that network latency is an obvious crutch in thin-client applications. We alleviate this issue to some extent by coming up with an Agent-based solution on the client with a server-side mediator which will specify the what and how data is transported over the network. Keep in mind, the traditional push model for data can be both expensive to the client and server.

At JavaOne, we'll be talking about other approaches with AJAX and how component-oriented MVC (in general) not only supplements the complexity of UI constraints, but also is more agile than traditional approaches. JSF Avatar carries the torch in this context such that we've gone through the work, once, of defining our view and how the 'domain' of the UI relates; then we allow the client Agent to describe how it wants to interact with the view in an efficient and secure manner.

Related Topics >>