7

I'm working an a PHP/JS based project, where I like to introduce Domain Driven Design in the backend. I find that commands and queries are a better way to express my public domain, than CRUD, so I like to build my HTTP-based API following the CQS principle. It is not quiet CQRS since I want to use the same model for the command and query side, however many principles are the same. For API documentation I use Swagger.

I found an article which exposes CQRS through REST resources (https://www.infoq.com/articles/rest-api-on-cqrs). They use 5LMT to distinct commands, which Swagger does not support. Moreover, don't I loose the benefit of the intention-revealing interface which CQS provides by putting it into a resource-oriented REST API? I didn't find any articles or products which expose commands and queries directly through an HTTP-based backend.

So my question is: Is it a good idea to expose commands and queries directly through the API. It would look something like this:

POST /api/module1/command1
GET /api/module1/query1
...

It wouldn't be REST but I don't see how REST brings anything beneficial to the table. Maintaining REST resource would introduce yet another model. Moreover, having commands and queries in the URL would allow to use features like routing frameworks and access logs.

fischerman
  • 500
  • 4
  • 12
  • have a read about `REST` in the [Richardson Maturity Model](http://martinfowler.com/articles/richardsonMaturityModel.html), that alone can perhaps help answer your question(s) – Alexandru Marculescu Oct 14 '16 at 08:53
  • 3
    @AlexandruMarculescu Nice article. Unfortunately, I don't see how this helps me with my question. Don't REST resources just make my API more incomprehensible? I'm not saying my public doesn't have a model. I'm thinking of having DTOs for commands and queries. – fischerman Oct 14 '16 at 11:10
  • Possible duplicate of [Rest API and DDD](http://stackoverflow.com/questions/35700344/rest-api-and-ddd) – guillaume31 Oct 17 '16 at 15:39

2 Answers2

9

The commands and queries are an implementation detail. This is apparent from the fact that they wouldn't exist at all if you had chosen an alternative style.

A RESTful API usually (if done right) follows the conceptual domain model. The conceptual domain model is not an implementation detail, because it is in your users heads and is the a source for requirements for your system.

Thus, a RESTful API is usually much easier to understand, because the clients (developers) have to understand the conceptual domain model anyway, and RESTful interfaces follow the concepts of such a model. The same is not true for a queries and commands based API.

So we have a trade-off

You already identified the drawbacks of building a RESTful API around the commands and queries, and I pointed out the drawbacks of your suggestion. My advice would be the following:

  • If you're building an API that other teams or even customers consume, then go the RESTful way. It will be much easier for the clients to understand your API.

  • If, on the other hand, the API is only an internal one that is e.g. used by a JS front-end that your team builds, and you have no external clients on the API, then your suggestion of exposing the commands and queries directly can be short-cut that's worth the (above mentioned) drawbacks.

If you take the shortcut, be honest to yourself and acknowledge it as such. This means that as soon as your requirements change and you now have external clients, you should probably build a RESTful API.

theDmi
  • 17,546
  • 6
  • 71
  • 138
1

don't I loose the benefit of the intention-revealing interface which CQS provides by putting it into a resource-oriented REST API?

Intention revealing for whom? A client side programmer? A server side programmer? In the same team/org that maintains the domain model? Outside of that team/org? Someone on the internet who would access your API naively by just probing a starting URI with an OPTIONS request? Someone who would have access to the full API documentation with URIs and payloads structure?

REST is orthogonal to CQRS. In the end, no matter how you expose your resources on the web, domain notions will be reflected somewhere, whether in the URI, the payloads, the media types. I don't think using DDD or CQRS should influence the way you design your API that much.

guillaume31
  • 13,738
  • 1
  • 32
  • 51