REST and CQRS

1,285 views
Skip to first unread message

Polemann

unread,
Oct 26, 2010, 5:37:34 PM10/26/10
to DDD/CQRS
I've been reading a few posts on rest-discuss and I'm really confused.
I thought, and still think, that rest and CQRS is a great mix. When
you ask me for a resource I will provide you with the list of commands
that you can call on that resource and specify its URLs etc.

Does anyone have a good rest / cqrs sample they could point me too or
event just discuss how you used HATEOS to describe how you post
commands to resources.

Rickard Öberg

unread,
Oct 26, 2010, 8:32:51 PM10/26/10
to ddd...@googlegroups.com

We are using CQRS and REST(/HATEOAS) in my project, with great success.
Here's what we do:
Each path ending with "/" represents a selection in the UI. It could be
"/organizationalunit/123/" for a particular item, or
"/organizationalunit/123/projects/" for some particular aspect on that
item. The client always start by doing a GET on that resource, and
receives back a JSON description for that resource which contains:
1) List of queries
2) List of (available) commands
3) List of (available) subresources
4) Index data

The list of commands is typically used to enable/disable
buttons/menuitems/popups. The client essentially know what it is allowed
to do. Whether a command is there or not could be because of application
state, but it could just as well be based on user roles. The client
doesn't have to care: if command "x" is in the resource description,
enable button "x", otherwise not.

The list of subresources is typically used to drive a tabbed pane. The
component will map the subresources to views, and instantiate them as
tabs. Same as above, some tabs may not always be available because of
roles, and so the client doesn't have to understand this: it just
creates tabs for the links it finds.

The index data itself is what will be used to display information about
the resource. We try to use generic DTO's such as Link and Links
(serialized to JSON) as much as possible, and have client components
that knows how to "render list of links", "select from a list of links",
and so on.

Commands are represented as "/organizationalunit/123/commandname". You
can do GET on it for a form that shows what parameters it needs, and
with default values filled in. You POST to it to send the command.
Conneg is supported, either with headers or .json/.html/.atom suffixes.
The URL's look kinda pretty :-)

Whenever we can we try to not let the client know about how to invoke a
particular command. Instead it will first do a GET on a query to get a
set of links, display those to a user, and when a link is selected the
client POSTS to it without "knowing" what the link looks like.

Example: for a project we want to be able to add users to it. Project
itself goes here:
/projects/123/
and member list:
/projects/123/members/
A GET on that will show the current list of members, and a link to a
query "possiblemembers". A GET on that returns a list of links, each
named with the usernames of users not yet in the project, and links
pointing to "addmember?entity=someusername". The list is shown to the
user, and when a link is selected the client POST's it, without having
to know about e.g. "addmember" being a command. This allows evolution of
the REST API without having to change the client, which is kinda neat.

We also use ETags and lastmodified timestamps for optimistic locking.
Works quite well.

This is the gist of it. One more important detail is that the REST API
should expose your *usecases* and not the domain model. We got this
wrong the first time (as do most projects/blogs/articles I've seen), and
it was really bad until we realized to structure our API according to
the usecases in the client, at which point everything became supersimple
and logical. I wrote about this here:
http://www.jroller.com/rickard/entry/rest_api_for_infrastructure_domain

Code for the above can be found here:
http://waybuild.gotdns.com/nexus/content/repositories/snapshots/se/streamsource/streamflow/
Take a look at the "streamflow-web" module, and start from RootResource
to see the REST API. Framework for server+client is in "streamflow-dci"
module.

/Rickard

Raoul Duke

unread,
Oct 26, 2010, 8:37:45 PM10/26/10
to ddd...@googlegroups.com
On Tue, Oct 26, 2010 at 5:32 PM, Rickard Öberg <rickar...@gmail.com> wrote:
>> Does anyone have a good rest / cqrs sample they could point me too or
>> event just discuss how you used HATEOS to describe how you post
>> commands to resources.
>
> We are using CQRS and REST(/HATEOAS) in my project, with great success.

a clueless question:

i thought CQRS allowed for some arbitrary delay between the write
side's changes getting out to the read side, and that mostly it was a
one-way pipe. (people have asked before about how to e.g. show the
newly added item in the shopping cart right away instead of possibly
having some unknown delay and a "your cart will be updated shortly"
message.) how does my (mis)understanding fit with REST? seems like
with REST the command's results need to be known and returned right
away, rather than going through the write->read->ui delayed path?

sincerely.

Daniel Yokomizo

unread,
Oct 26, 2010, 8:42:42 PM10/26/10
to ddd...@googlegroups.com

The result must be returned right away, but it may be an 202 ACCEPTED
instead on an 201 CREATED, for example.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html


> sincerely.

Best regards,
Daniel Yokomizo

Rickard Öberg

unread,
Oct 26, 2010, 8:54:13 PM10/26/10
to ddd...@googlegroups.com
On 2010-10-27 08.37, Raoul Duke wrote:
>> We are using CQRS and REST(/HATEOAS) in my project, with great success.
>
> a clueless question:
>
> i thought CQRS allowed for some arbitrary delay between the write
> side's changes getting out to the read side, and that mostly it was a
> one-way pipe.

That's one way to do it.

> (people have asked before about how to e.g. show the
> newly added item in the shopping cart right away instead of possibly
> having some unknown delay and a "your cart will be updated shortly"
> message.) how does my (mis)understanding fit with REST? seems like
> with REST the command's results need to be known and returned right
> away, rather than going through the write->read->ui delayed path?

In our version the command is processed synchronously and the list of
events (or the error if it failed) is returned to the client, at which
point it can do a refresh of its view. We update our snapshot and graph
querying index synchronously with the request (which is what we need for
the main views), and RDBMS and search engine (Lucene) asynchronously.

There's a ton of options here, and only you can decide what's right in
your case. Just know about what the options and tradeoffs are.

/Rickard

David Leangen

unread,
Oct 26, 2010, 9:08:14 PM10/26/10
to ddd...@googlegroups.com

Rickard, you are my idol! (*-*)/

It's difficult to comment more, since I've never yet tried your
approach, but it just seems so right on so many levels. I look forward
to trying it sometime, hopefully sooner than later.


Cheers,
=David

Elliott O'Hara

unread,
Oct 26, 2010, 9:16:03 PM10/26/10
to ddd...@googlegroups.com
Rikard,
Please tell more...




On Tue, Oct 26, 2010 at 8:08 PM, David Leangen <david....@gmail.com> wrote:

Rickard, you are my idol!  (*-*)/

It's difficult to comment more, since I've never yet tried your approach, but it just seems so right on so many levels. I look forward to trying it sometime, hopefully sooner than later.


Cheers,
=David



On Oct 27, 2010, at 9:32 AM, Rickard Öberg wrote:

On 2010-10-27 05.37, Polemann wrote:
I've been reading a few posts on rest-discuss and I'm really confused.
I thought, and still think, that rest and CQRS is a great mix. When
you ask me for a resource I will provide you with the list of commands
that you can call on that resource and specify its URLs etc.

Does anyone have a good rest / cqrs sample they could point me too or
event just discuss how you used HATEOS to describe how you post
commands to resources.

We are using CQRS and REST(/HATEOAS) in my project, with great success. Here's what we do:
Each path ending with "/" represents a selection in the UI. It could be "/organizationalunit/123/" for a particular item, or "/organizationalunit/123/projects/" for some particular aspect on that item. The client always start by doing a GET on that resource, and receives back a JSON description for that resource which contains:

1) List of queries
2) List of (available) commands
3) List of (available) subresources
4) Index data

The list of commands is typically used to enable/disable buttons/menuitems/popups. The client essentially know what it is allowed to do. Whether a command is there or not could be because of application state, but it could just as well be based on user roles. The client doesn't have to care: if command "x" is in the resource description, enable button "x", otherwise not.

Rickard Öberg

unread,
Oct 26, 2010, 10:05:05 PM10/26/10
to ddd...@googlegroups.com
On 2010-10-27 09.16, Elliott O'Hara wrote:
> Rikard,
> Please tell more...

If you have a specific question, sure. Otherwise it's kind of hard to
know where to start. It's a huge topic.

/Rickard

Rinat Abdullin

unread,
Oct 27, 2010, 12:30:32 AM10/27/10
to ddd...@googlegroups.com
A blog post or a series maybe? ))
I'd love to read more about that.

Best regards,
Rinat Abdullin

Technology Leader at Lokad.com | Writer at Abdullin.com | Contacts

Polemann

unread,
Oct 27, 2010, 3:02:26 AM10/27/10
to DDD/CQRS
Rickard,

Thanks for the example. I like it when solution make sense. I'm going
to try and get my service defined and coded using similar principles.
That is a very sensible use of a 'rest-like' interface with CQRS.
( can't say rest cause I'll get shot at by one of the protagonists)

2 quick q's :

I see you've spoken about links specifically based on users
permissions. Is it just a case that you look at the object and the
user permissions and then decide to show the link or otherwise. This
is a good real world example not my user wants to update his bank
account so I send in the new balance... ha-ha that sounds silly.

Are you returning the structure of your commands in the payload as
well or just via links. If I was to use an xml appraoch I woulc
imagine that I woul just supply an XSD that had the command format in
it for people to consume.






Scott

Polemann

unread,
Oct 27, 2010, 3:05:51 AM10/27/10
to DDD/CQRS
Here's another link to the same ideas from Rickard.... someone replied
to some of my other rest questions about it.

http://iansrobinson.com/2010/09/02/using-typed-links-to-forms/

Rickard Öberg

unread,
Oct 27, 2010, 3:15:08 AM10/27/10
to ddd...@googlegroups.com
On 2010-10-27 15.02, Polemann wrote:
> 2 quick q's :
>
> I see you've spoken about links specifically based on users
> permissions. Is it just a case that you look at the object and the
> user permissions and then decide to show the link or otherwise. This
> is a good real world example not my user wants to update his bank
> account so I send in the new balance... ha-ha that sounds silly.

Something like that. Based on the policy of the object being accessed,
and the user accessing it, you present links based on that
(authorization). The links that is provided to the client gets enabled
in the client UI, and the rest are not shown or are greyed out.

For banks, there might be several types of users accessing a bank
account, and some may be allowed to see balance, some may be allowed to
make payments, and some may be allowed to make transfers. Different sets
of links are provided, and the client just reacts to it.

> Are you returning the structure of your commands in the payload as
> well or just via links. If I was to use an xml appraoch I woulc
> imagine that I woul just supply an XSD that had the command format in
> it for people to consume.

In my case the client gets the set of links. Either I have preprogrammed
the client to "know" what to supply when POSTing to it, or the client
first does a GET on it to get fields that needs to be filled in and then
fill in what it knows and POST it. Or a more dynamic client might
present the fields to the user dynamically to be filled in. Very similar
to how a browser would. In fact, your client will become more and more
like a browser as you continue down this path, as you get more
hypermedia-driven.

/Rickard

Reply all
Reply to author
Forward
0 new messages