Is a REST API with CQRS Possible?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

TLDR: Yesh.

👍︎︎ 9 👤︎︎ u/[deleted] 📅︎︎ Mar 10 2021 🗫︎ replies

Not sure why he captioned the post this way lol

👍︎︎ 2 👤︎︎ u/samiroker 📅︎︎ Mar 10 2021 🗫︎ replies

Thanks for the excellent video /u/codeopinion! Love watching all your videos as they come out, each one really spot on and insightful.

One question I have is, say we split read and write services, the write services obviously belong to the domain model along with entities, repositories and such; but the read services I am less sure. Should they be in the application layer or domain layer? (I.e., in a typical 3 tier app/domain/infra setup)

Many thanks!

👍︎︎ 1 👤︎︎ u/jesparic 📅︎︎ Mar 11 2021 🗫︎ replies
Captions
if you're moving away from crud and towards a task-based ui with cqrs like i've described in some of my videos a common question i've been getting is well how does that work with the rest api so i'm describing what the differences are between a typical rest api that really revolves around entities and crud and how you can map commands and queries to resources hey everybody it's derek martin from codopinion.com if you're new to my channel i post videos on software architecture and design so if you're into those topics make sure to subscribe all right so the first thing to clear up before i even get into this is the term rest now i'm going to be talking about http api because that's really what i think the developer community at large is referring to when they use the term rest and that's totally cool there's nothing wrong with an http api it's exactly what i'm going to show today all right so through this video i'm going to be talking about um kind of a warehouse domain for a product and i've been using this slide i kind of have this entity that is a product it has a sku that's the identifier the name description the sale price the purchase cost from a vendor the quantity like the quantity on hand in the warehouse whether it's for sale and with free shipping so i think some of the problems that are stemmed and why people are confused about how secrets and an hdpi http api work together is that there's this notion that http methods need to map to sql for example if you're using a relational database so there's this concept out there i don't really know how it got this overblown is that you're thinking of that a get is a select that a post is an insert that a put is an update that a patch is like a partial update and it deletes a delete so if we were thinking about how that actually maps out to a route you'd be thinking okay i can call get on slash product slash whatever the sku is that will give me back that entity or that object if i call post to slash products that's going to add a new product to my collection my entity collection a put will be a full um update so i would pass the entire object back to slash products and whatever the sku is same thing for patch for a partial update and a delete as a delete so there's this notion that you have to have this all this very crud behavior and that resources must be entities and i i'm kind of lost on how this got that uh as a common con misconception in my view of how this actually needs to work which it doesn't at all so i'll explain how actually commands and queries because because you're really not doing crud anymore how that maps to resources rather than resources being entities your resources are going to be commands and queries so my video talking about task-based uis i used this ui that was very crud in nature and you could think of it if we were talking about what we were doing before where you click save and that would be doing a put to the particular product slash whatever the sku is and then i kind of redesigned this ui to actually be more task centric and then in doing so kind of the realization where the boundaries are that it's not necessarily one product that it's probably multiple products or the concept of a product that lives in different boundaries so you could have a product that lives in catalog that contains like the name in the description and then there's for example the sale price some other properties that belong to sales the purchase price from the vendor manufacturer that actually belongs to purchasing and then the quantity on hand actually belongs to the warehouse so how does that map to an http api is exactly that the commands and queries are going to map to resources so under the catalog i'm going to be able to call a get to a particular catalog say for example catalog slash products in a particular sku if i wanted to update that product i can do that cruddy nature of thinking of an entity service if you will and that makes sense partic particularly in a catalog maybe i don't have any specific tasks related to it but then in sales okay i can get the particular product and that will give me things like the the sale price whether it's for sale or if it's unavailable and whether it's free shipping and the the particular pieces of data that are applicable to sales and the the piece of data it owns and then instead of just being having this okay i need to update the entire product or do particular patches and then it kind of infer what the actual change is if you're gonna have some particular command or action or task like increase in the price that is a particular resource so you're for example doing a post to that particular ink to the increased price now using if you care about the semantics of the methods which i think you should then realize that there was kind of method to the madness of trying trying to map particular methods to sql but it doesn't necessarily fully make sense for example because a put needs to be item potent and if you want to make these particular commands item potent which you can and i'll probably cover this in other videos so make sure to subscribe and but for simplicity's sake i'm saying when you call a post to that particular resource and you're increasing the price it's going to happen so the same thing with decreasing the price marking is something available or unavailable those actually could be potentially item potent just naturally so those could be puts same thing with purchasing same thing for the warehouse that the particular commands are particular resources a resource can be whatever you want it to be it does not need to revolve around an entity so i'll definitely harp on this more in other videos and i know it's a kind of a touchy subject to people and a lot of people have various opinions but the reason why i say that anything can be a resource is because it can be a resource is anything that has an identifier so if you look on the mozilla docs you know i mean a hp request is called a resource whose nature isn't defined further it can be a document a photo anything else again it does not need to be an entity all right so i cover commands and how those are resources but then the question often becomes okay well how does a ui work out well you kind of got two options and i think a lot of this is can be a mix and match in which option you choose so if you it's really about where you want to do the composition to build out your ui so one option is to do that common composition on the actual client that means that your client is going to call multiple different resources from multiple different services or boundaries to get the relevant data and needs for the particular ui that it has so that means that like the catalog has its own resource to provide this information sales has its information that you to for the like for changing the price and showing the sale price the warehouse has the quantity on hand so what that means is is your ui is making multiple http calls to those various resources to build out its ui so the catalog might provide this particular set of information the sales might provide its resource might provide this particular piece of information to build out this ui the second possible scenario here is to do all that common uh composition on the server so instead your client is actually only making one http call to the server and it's going to do the composition by fetching all that data concurrently from all the different boundaries and then turning all that data into one particular response for your client so instead of having all this disparate data everywhere it's going to do that but then combine it into something that contains the sku the price the name the description i left it out here but the quantity on hand and all the other things that can build out that one big ui so it's really about where do you want to do that composition do you want to do it on the client or do you want to have one particular resource that your client goes to that it does the composition for you so i'm going to show my demo app that is using asp.net core i'm going to show the project structure of these controllers and where the routes are as well as just vanilla javascript and html if you are a code opinion developer level member you'll get access to all the source code if you want to get access to source code and become a member go to my channel click the join button for more info alright so here's the project structure i have in espnet core i have a couple different projects here just for illustration purposes i have this asp.net core project it really doesn't have much in it other than it's doing the host for asp.net core and it's referencing all these other projects so if you're familiar with my loosely coupled monolith series i'm kind of playing with that a little bit here it doesn't necessarily need to be split by project i'm just doing it just for illustration purposes that these are separate boundaries so under the catalog i have a entity framework db context and i have a product controller that does probably kind of what you typically think is i have a get method that returns the product and i have a update method for this particular route that is a put that updates the particular product if i keep going on here uh for purchasing i kind of have that exact same structure for sales in the warehouse so in sales i have a command for increasing the price which is just that particular uh route for posting like i mentioned earlier and we're just increasing the price and then in the warehouse i flipped it up a little bit because i knew people were going to lose their mind or comment about having code in your controller and everybody's high on mediator i posted videos about mediator too so just to switch things up i have an inventory adjustment where i'm using mediator instead to actually create a particular request that represents my command and then i have a handler uh that does that logic and then i'm also publishing an event here that i'll kind of illustrate all right so i'm in my little demo task based ui that i created this is just plain html and vanilla javascript for the most part just using fetch to make the http calls so this was kind of the crud portion when i load the screen we'll refresh it we'll see the various because i'm doing all the composition on the particular this particular page so i'm making various calls here i'm making a call to the warehouse to get the quantity on hand i'm making a call to the catalog to get the the name and the description so if i go to preview we can see that data and then i'm making a call to the sales side to get the uh the product as well for the price and everything else so i get we can see the sku the price which is the 85. all right so let's do something simple like we're going to do this save we change something with our title for example we're going to call save so this is hitting my just that kind of cruddy nature of in the product controller for catalog we're just calling our update just to update the entire product if i jump back over to devtools here we can see that was our call we were calling a put to catalog products abc123 and now i'm just returning a 204. all right so the other command i had was for in the sales side was increasing the price so this one's pretty straightforward as well we're at 85 dollars i'm gonna be at a hundred dollars let's say so we're going to call increase price and what i'm doing here is i'm just updating the price in line returning a no content and if we look on the server side though so that was the call that we made return the 204 we sent the relevant data if i can see the price there and then what i did afterwards is once this returned and it was successful i then called back our api for the sales to actually get that product back so this would be very typical of what you would see in a typical post redirect that you would do in something like mvc if you had a particular form where you were calling a particular post to update the price or do whatever your command is and then it would ultimately use a location header to redirect you back to a particular page which you would then be refetching all the data to populate the page i'm not using the location header i will in a future video when i'm talking about hypermedia but it's kind of that that redirect kind of pattern that you're using all right so this last example i have of doing a inventory adjustment is really to me the heart of the whole thing and why you want to be doing this in the first place the reason why you want to get away from crud and get into tasks and commands is because you're making things explicit of what users are doing if you know what they're doing then you can do other things based off workflow based on that so here's my example of this so we have our 15 quantity i'm going to do an inventory adjustment and i'm going to say that um it's not 15 we actually can't find all of those and we can really only find four of them so i'm going to do my inventory adjustment basically removing 11. so here now i'm calling that particular route uh for doing my inventory adjustment and this was using mediator so i just basically my actual route itself is ultimately very slim just calling mediator and then in my particular handler i have some logic here where so i'm updating the actual um quantity on hand i'm saving it and then what i'm doing is i'm publishing an event now again this is all in line because it's using mediator but if you're thinking about using events and messaging this is what it's really applicable to is because now you said okay we did an inventory adjustment so inventory was adjusted that's the event that i'm publishing i'm going to be publishing that event with information about the sku and the quantity on hand what's really important about that is that now we can have other parts of the system of their boundaries react to that event and then possibly do other things in which case i'm going to do so i'm publishing that inventory adjusted event and now what i'm in i'm actually in my warehouse side and maybe we have some workflow that says okay if the particular quantity on hand for a product gets below a particular threshold in this case i've deemed it i think five then what we're gonna do is we're gonna create a purchase order requisition so that purchasing can know okay we're really low on this particular quantity let's reach out and place a purchase order to our vendor or manufacturer to basically get more quantity on hand to increase our stock count so in this particular case yes we are we've reached our threshold threshold so now we need to send another command into our warehouse to say okay let's create a purchase order requisition that's really the big benefit of getting into commands and tasks is because you're being explicit if you know exactly what the user is doing and what their intent was then you can create relevant commands based off what just happened and then events you can ultimately use in other parts of your system to decouple them to know that this happened in this part of the system maybe i need to be reactive and react in a particular way that i need to do something else in another part of the system so if you're using seeker s and you're using task based uis creating an http api is really just as simple as creating resources for your commands determining whether you want to make them item potent or not or whether they're naturally potent and then use the appropriate http methods based on that where you want to do your composition for your query side that's really up to you whether you want to do them on the client whether you want to do the composition on the server you'll have to figure that out now i will go into deeper dives in this but for sure the thing i want to cover the most now in my next upcoming video related to this is using hypermedia and really the value behind it for your clients to show your clients these are the actions this is the things that you can do based off state if you enjoyed this video please give it a thumbs up if you have any thoughts or questions make sure to leave a comment and of course if you haven't done so already make sure to subscribe for more videos on software architecture and design thanks you
Info
Channel: CodeOpinion
Views: 12,258
Rating: 4.9422679 out of 5
Keywords: REST API with CQRS, software architecture, software design, cqrs, event sourcing, design patterns, software architect, asp.net, soa, microservices, event driven architecture, azure service bus, distributed transactions, message queue, message queuing, messaging patterns, service oriented architecture, microservice architecture, domain-driven design, rest api iwth cqrs, rest, rest api, restful web services, rest webservice, http api, .net, .net core, Asp.net core
Id: 6XO6vSiioWE
Channel Id: undefined
Length: 16min 46sec (1006 seconds)
Published: Wed Mar 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.