views:

54

answers:

4

Imagine some kind of a banking application, with a screen to create accounts. Each Account has a Currency and a Bank as a property, Currency being a separate class, as well as Bank. The code might look something like this:

public class Account
{
    public Currency Currency { get; set; }
    public Bank Bank { get; set; }
}

public class Currency
{
    public string Code { get; set; }
    public string Name { get; set; }
}

public class Bank
{
    public string Name { get; set; }
    public string Country { get; set; }
}

According to the REST design principles, each resource in the application should have its own service, and each service should have methods that map nicely to the HTTP verbs. So in our case, we have an AccountService, CurrencyService and BankService.

In the screen for creating an account, we have some UI to select the bank from a list of banks, and to select a currency from a list of currencies. Imagine it is a web application, and those lists are dropdowns. This means that one dropdown is populated from the CurrencyService and one from the BankService. What this means is that when we open the screen for creating an account, we need to make two service calls to two different services. If that screen is not by itself on a page, there might be more service calls from the same page, impacting the performance. Is this normal in such an application? If not, how can it be avoided? How can the design be modified without going away from REST?

+2  A: 

it is normal and can not be avoided... ...unless you create a specific service that returns all the data for a specific screen in one run.

This is one of the negatives of the REST approach - basically if you deal with object queries, and you need lists of x objects, then you have x calls. Point.

Which means REST designs have limited scalabilit on that level.

Again, as in the start - you can always have a specific service returning all data you need on a complex form in one call.

TomTom
How can I implement a service which returns multiple result sets (knowing it is not RESTful)? If I'm using JSON what would be the response and how can I handle it on the client?
Slavo
Sorry, but it is plain wrong that you need to make N calls to retrieve a list of N items. If you need a specialized view into your application for whatever reasons (e.g. whole item list in a single view) then just define a resource that has the appropriate semantics. TomTom, please do not make statements about REST that are not true.
Jan Algermissen
@Jan, it is not N calls for N items. It is rather N calls for M items, where N is the number of resources you need a list of, M is the number of items in a list.
Slavo
@Slavo, simply improve the resource model to reduce the number of calls. There is no need for retrieving the items individually (unless a stupid service forces you to do so - which it won't because it simply increases it's own load).
Jan Algermissen
Exactly. One call to get countries, one to get accounts, one to get.... at the end you make X calls for X different lists, and that gets - as the user said - quite heavy quite fast. Alterantively you make a view that returns countries, accounts .... in ONE call.
TomTom
+1  A: 

Hang on, ReST is about representing resources.

I don't think you should be too strict on the following:

According to the REST design principles, each resource in the application should have its own service, and each service should have methods that map nicely to the HTTP verbs.

It should be perfectly fine that the resource your representing in the browser is a "form" and contains all the relevant information.

Just think about the right degree of abstraction when defining your URL structure.

dwightgunning
In some unrelated cases, I also need separate calls for the separate objects (i.e. only a list of banks), so I cannot take the form as a resource. Or at least it would be much cumbersome and dirty.
Slavo
Suggest you take a look at some vintage Joe Gregorio: http://www.xml.com/pub/at/34
dwightgunning
@dwightgunning "Just think about the right degree of abstraction" just nails it. Though I'd say "when defining your resources" and not "URL structure".
Jan Algermissen
Actually, I think it's both in equal parts :-)
dwightgunning
A: 

Slavo,

there is no need to provide different services for different resources. In general, you should simply provide the views that help your clients achieve their goals. If one of such views is an integrated 'big' view (resource) including all the banks and currencies then that is fine. You still can provide fine grained views (resources) for authoring and editing banks and currencies.

If the banks and currencies happen to be provided by different Web applications and you need the client to resolve the references, then keep in mind that HTML pages do this all the time with inline images. Caching goes a long way to reduce the number of network calls in such scenarios (and the list of banks and currencies seem not to be very volatile).

(See http://www.nordsc.com/blog/?p=152 )

Example:


GET /service/account-management

200 Ok
Content-Type: application/vnd.my.accounting
<page>
...
<banklist href="http://other.org/service/banklist" type="application/atom+xml" />
<currencylist href="http://standard.org/currencies" type="application/rss+xml" />
...
</page>

The sub requests to banklist and currencylist should be served from the client's private cache most of the times.

Jan

Jan Algermissen
The editing/inserting of banks and currencies does not happen in the same view, so it is irrelevant. As far as I understand, you are saying it is OK for my resource to be the form, and the response of the service to be a list of currencies and a list of banks. If so, the question becomes, how do I return multiple result sets, as I asked in the comment to TomTom's answer.
Slavo
Simply design all the resources you need to enable what you want to enable. There is no problem if they overlap. If you want a resource to represent multiple result sets, just make it that way.
Jan Algermissen
+2  A: 

It's an architectural decision that you should base on the size and complexity of your system. The more large/complex your system is, the more it's likely to benefit from increasing levels of separation/encapsulation (for example, you may find that BankService needs to scale more aggressively than CurrencyService, and running these services separately will allow you to do that).

What I would point out in response to your question, though, is that you should be considering caching the results of these service calls and reusing the result, rather than re-calling the service for every page load. If (as the names would suggest) the result of CurrencyService and BankService are not likely to change very often, you could cache them for minutes or hours at a time and not have to repeatedly make those calls.

If your application is busy (that is, if you think in terms of hits-per-second rather than hits-per-hour) then this can save you memory at runtime since the result of a single service call is shared between multiple page requests (rather than each page needing to get the result set separately).

Dan Puzey
Yes, you are right. Caching on the client would solve that. But as a concept, the architectural style does not depend on caching and still has this practical limitation. I was wondering if there was a design change that could solve the problem.
Slavo
If you're being strictly RESTful then Bank and Currency should have different URIs, since they're different entities. But there's nothing to stop you creating a (read-only) service that could return both lists as one entity. That said, you'll end up needing such services for every other screen, and your design will suffer. Ultimately, the tiny perf overhead is the price of a well-encapsulated REST architecture (just as you pay a tiny perf hit for multiple DLLs vs a mammoth .exe, or for method calls vs inline code). This shouldn't be the biggest concern you have in terms of performance. :-)
Dan Puzey
Alright, I guess that's the best I'll get. Thanks :). upvote limit reached, back tomorrow.
Slavo
@Slavo, you keep making claims about REST that are not true. If you look at Roy's lattice for deriving REST you'll see that the Cached-Client-Server still is an essential part of REST. And: REST does not have the problem you keep talking about.
Jan Algermissen
@Jan, I'm not making any claims, just trying to solve my problem. If what Dan suggests here is OK and still RESTful, even better. I don't know if it is REST or not, that's why I asked the question.
Slavo