3 ms·
The problem described isn't a technology problem. It's a business domain problem, and it should be solved by fixing the domain modeling. The example doesn't un
by jonahx 12y ago
The problem described isn't a technology problem. It's a business domain problem, and it should be solved by fixing the domain modeling. The example doesn't uncover any problems with REST architecture.
If prices are changing and you need to capture them, the "Product" concept isn't enough. You need to model the concept of price, and perhaps price change events too. So a customer doesn't buy a product, but a product together with a "ProductPrice".
- jdmichal 12y agoI generally don't understand the example. An "Invoice" object should capture everything relevant to the purchase, including prices, taxes, shipping, etc. Identifying a "Product" via ID is fine, and that Product may even have a "current price" attached to it. But in no way should that referenced Product object impact the captured Invoice object.
- keyle 12y agoI really like your idea of an invoice or ticket for a specific instrument of product price/time.
- johnwalker 12y agoComing up with names for groups of data that you want to be atomic isn't that useful, though.
- jdmichal 12y agoI don't understand. That's exactly what domain modeling is. Putting names to the data you need to store and, in this case, capture at a particular moment in time. Let's put it this way. Do you think it is reasonable to store the taxes as a reference, or the shipping cost? We would never consider it appropriate to say, "Go look up the shipping cost for a 5lb package from here to here." Oh, and by the way, this is using a live reference to a customer object, for which the shipping address might very well have changed. Of course we would not do this. So why would it appropriate for a product price? An invoice is the capture of all this information at the moment the purchase is made. That is its purpose. If we did not need this moment-in-time capture, then the concept of an invoice would not even exist.
- innguest 12y agoComing up with names for groups of data that we want to consider as atomic is what object orientation does, it seems to me. I also think that that is its Achilles heel - by giving names to groups, only those privy to the internal representation of the atom can combine their functionality with its data. So you need to either merge your functionality with the atom's data (aka define an instance method) thereby coupling "things" with "actions", or you need to leak the atom's internals to outsiders (aka write a method somewhere else that "knows too much" about the atom's internal representation).
- Arnavion 12y agoFTA: "To patch it up, we attach the product price to the order..." The author already discussed attaching the price to the product into a ProductPrice. His argument continues that price is only one thing, there may be more. FTA: "If our analytics department needs to know the product category for their reporting, or if our accounting department needs to know cost-of-goods-sold for revenue calculations, we must attach these as well, as they may change over time. As these requirements grow, you end up sending more and more of the object graph attached to the order, just to maintain consistency for everything that happens after-the-fact." He's essentially extracted all this information out into its own class caleed "State" which can be referenced by a single ID and passes that along with his product, a ProductState if you will.
- jonahx 12y agoAll of his examples should be solved at the domain level. They just don't have anything to do with REST architecture. The information doesn't need to be sent over the wire. There are many ways to solve it, but at the end of the day all that needs to be sent over the wire is the product and the time of purchase. Everything else can be deduced on the backend, and how hard that is to do will depend on how well you've modeled the concepts your interested in.
- devuo 12y agoCompletely agree. It's problem at the domain level, and not in REST per se.
- baddox 12y ago> His argument continues that price is only one thing, there may be more. Indeed. A new model is needed, and that new model would have all the relevant attributes. I can think of two ways to do this (using ActiveRecord-ish naming conventions). One way would be to have an InvoiceRow to represent the presentational details of each row in an Invoice, like name and price, perhaps along with a reference to the actual model it came from, like product_id. The Product model could change, but the Invoice would still have all the InvoiceRows it needs to display and reason about that invoice without fear of mutation. Another way would be to have a robust versioning system. So a Product might have only an id, and there could be many ProductVersions that hold all the real info (name, price, etc.) and reference the same Product via product_id. ProductVersions would of course be immutable. Then the Order model in the example would return product_version_id, and could therefore look up the actual name and price at the time the order was made. For the narrow example from this article, I think the first example fits better and is much simpler.
- rubyfan 12y agoI agree here, the problem is with the author's contrived example. This domain problem can easily exist within a relational database, rest, soap or even snail mail. The problem is a poor domain model and should be fixed there and not by adding an overly complex cache or state object storage solution that seems to only apply in a REST model. If the domain model is fixed then REST, soap, RDBMS or anything else becomes trivial.
- scottashipp 12y agoJonahx your response summarizes my feelings pretty well. To add to this, I found the post perplexing considering that REST also has cache constraints as described at http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_4 http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch.... This makes some statements in the article strange. For example: "Very rarely will a RESTful URL specify an Expires header . . ." Leaving aside that Expires is not the only cache header http offers (see http://odino.org/rest-better-http-cache/ http://odino.org/rest-better-http-cache/ for others), the main problem with this statement is that it suddenly makes the system he is describing not-quite-RESTful. It raises the question are you really in a RESTful style if you throw your hands up and ignore the cache part of the style. I would say that ignoring cache is an assumption that Dziuba is making which partly results in the problem he describes, along with having incorrect domain modeling. Restore the cache piece to the system and it would be able to deal with the stale-price-problem just fine by noticing that the price is stale and requesting a fresh one.