DDD & REST - Domain Driven APIs for the web - Oliver Gierke

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to this session on DVD and rest while still a couple of folks coming in my name is Olle öberg yoga I work for pivotal the company that's hosting that conference here I'm this spring data Project Lead so working with a couple of other spring engineers on data access related topics but I have a bit of a history in consulting and for SpringSource back in the days and helping a lot of customers to build for example restful api s and that basically led to me getting in touch with or rest concepts and the spring data side of things especially the repositories with the DDD concepts and it turns out that like a basically a triangle of projects from that area has some or made up some connection some interesting as I said the first thing the spring data repositories and the fact that like the entities that you that you deal with in your application sort of forming aggregates by the virtue of the fact that you have a repository for them the other the other part that played into that is that from those consulting gigs where we build restful api is with customers we extracted a library called Springhead us for not for hate oracle application server but hypermedia as the engine of application state it's basically a library that you would use like Apache Commons or something in your spring MVC application and it makes it easier to add hypermedia elements to your json representations we go into that in a bit later on and bringing those two things together like round about two or three years ago we started to think okay there are these repositories and these aggregates and we have this this library that deals with hypermedia aspects of rest can we bring them together and actually build a framework that makes it easier or covers certain patterns implement certain patterns rest patterns on top of these burries that's what spring that arrest basically and I'll be going to talk about that in in detail and cover the advanced part of the library in a talk on Thursday but I bring that up here because that building that library that spring that arrest library made us think about okay what what's the best way to let's say set up resources for a certain domain model right so while the casual reader might just think okay we're just exposing data by arrest which we sort of do but actually then again not do all that development basically let me think about okay what what is it what we're actually doing here how do these domain driven design concepts translate into into into the restful world and what can we maybe learn from the domain driven design idea in terms of writing restful api s and the talk basically is a summary of exactly that right so the questionnaire that I would like to answer in this talk because it's basically two questions the first one is when we're designing restful api s-- what we can we learn from ddd which concepts can we actually transfer which concepts can we maybe not transfer and that's that's and i some ideas i'd like to give you in the next like 50 to 60 minutes and by that also looking at let's say you have an existing application and you have your domain classes your entities or aggregates in there what is a good way to actually build or how do you actually build a good restful api on top of it is the easy way make an entry source for every entity is that really a good way what consequences does that approach have and is there maybe a better one right all right so to get the elephant out of the room who is read the book till the very end ah sheesh that's only 20% of the people who originally raised the hands there's an alternative to the to the book that I recommend for those of you who have new to this topic in on info queue a PDF basically a 100 page summary of the most important parts or the distilled version basically of the actual book the actual book is still worthwhile reading I'm totally not saying that but it's kind of more verbose version and it's very a storytelling like and it might just like might get lost in some of the details and if you're reading it in the first place however the fundamental idea is how do you actually tackle complexity that's what the subtitle says in software development so Eric basically starts from okay we need to build a ubiquitous language that the business people speak and somehow find find that language in the first place and then find means to actually translate these this language into the code right so basically bring the code in the business together there's a it's basically there are two two fundamental aspects or parts in the book the first one is the building blocks of TDD and that's what we're going to look at because I think they're very important when it comes to later on to building rest api is on top of a domain model the building blocks and the other part is strategic design basically how to cope with change how to evolve your models how different systems basically which roles they take when interacting with each other and stuff like that alright so the if you've read the book you probably find this this graphic familiar it's basically the building blocks in relation to each other we're going to look at those for the entity's repositories aggregates and value objects because I'm not because they are like special within their group here in general but because they are the ones that are I think the most important ones when it comes to are they how they actually embodied embodied in the in the code base and their effect on the way we build the rest api is on top of them later on right so let's start with having a look at how you implement those patterns I don't want to I mean we briefly discuss what a value object is but I don't want to go too deeply into that but rather look into how do how do these elements actually get implemented in the codebase and what consequences does that have on on restful api s-- so the first thing the first first building block the most tiny building block is actually value objects so who of you has seen code that looks like this I call this string any type code right everything is a string you can even extend that type of programming to object-oriented code which is then every field is just object right but what's the problem with that kind of code yeah well you write methods that look like this right they take a first name and take a last name to take an email address and guess what it's very easy to mix those up right even worse when someone pipes in a string for the email address how do you actually know that it is an email address right the code that's called like the implementation of the method can never be sure right you have to rely on someone somewhere having validated that thing so and the idea that every brings up is to create so-called value objects they are basically like typed representations they make domain concepts explicit that's a recurring theme we're going to see about in the course of the talk making things explicit so by half saying I have a string email address you completely lose the notion of all the business rules that are surrounded by an email address so an email address is not an arbitrary of string right an email address is an email address is an email address and you can actually express that by introducing those dedicated types for those primitives some people try to do that here as well even go as far as saying there shouldn't be any Java primitives in in your domain classes at all so you even go ahead and do things like first name and last name what have you there's certain shades of gray there I think but especially the email I like the email address example very much because there's like real structure to that string that you can actually validate and by validating or or by enforcing that structure in inside the email address class your domain becomes really expressive and it actually has a real real benefit to to the coders we're going to see in a minute so the problem is that value objects are quite hard to not to get right necessarily but there's a lot of boilerplate to be written in some languages read Java right you need to create a like a class with final fields you need to take a constructor and or rather have a constructor that takes the arguments you need to implement hat equals and hashcode correctly all of that crap yeah other languages like in scala you have case classes they are they are much more comfortable and doing that i mean i just mentioned that because the or the point i'm trying to get across here is although that might be considered a bit more effort to implement those types there is some pay off in the long run and you're going to see that as a recurring theme in in the talk as well i still argue they're worth it in in case you want to I mean there's like it's like what the number one rule of ddd talks is if you talk about value objects you need to mention done dance talk the power use of value objects i think it's the most refer to talk that i have at least in my slide decks definitely recommend that ease but here's basically a one-hour talk on where he takes some code like 200 lines of totally undigestible code it deals with currency exchanges and then he starts to introduce value objects only value objects in their very code and by all of a sudden it becomes more testable it becomes more readable it becomes simpler so definitely check out this one and the solution or one of the solutions that are available in java to actually not have to write all the boilerplate is a project called Lombok has anyone ever heard of Lombok okay couple of you guys so for anyone watching the recording later on you basically use some annotations and an annotation processor so it's basically a compile time step in this case with at value and you have these like assuming first name and last name are value types again you see that value class down there email address you just have properties in there and Lombok basically turns every field into a private final field creates a constructor taking all the fields implements equals and hashcode correctly all the stuff that I just mentioned to be boilerplate right cool stuff there is a auto value from Google I think it's using interfaces and also some cogeneration going on behind the scenes so there's there are alternatives just the quick thing very objects good thing don't shy away because of the additional overhead that you might think you need to invest here going on to entities and repositories they usually make up the core of our domain model the entity side say so just imagine arbitrary like model here I'm just like pulling bubbles and arrows up to to have something to talk about and you relate to so we have this customer here has an email address some payment information an address we have invoices that are issued for the customer so we're sort of building an e-commerce system there is orders that are placed by the customer right so they belong to the customer the orders of line items of course and the line items in turn point to a product right so very very very standard thing here and superficially you might think okay what's the deal and there is a lot of information in that graphic even or in that model that becomes very crucial in terms of like your domain design and you might not even see it right now but in even in terms of the API design that's feasible or not feasible to be built on top of that so the first thing that you should realize is that like these these bubbles are kind of clustered already so what we have here implicitly is the concept of an aggregate right so that's basically the the or if the the definition in the book is basically you have a group of entities where one entity and that's the ones I've underlined here is sort of controlling business rules and consistency rules over a set of entities right so the best example usually is is the the order over there with with the line items here and the point being that you'd never go ahead and manipulate line items on their own you'd never like just issue an insert or it go to the database and say please go ahead and insert a new line item but you'd rather go ahead read the order programmatically add a new line item because that process of adding the the line item would actually allow you to to check certain business rules right you need to have a minimum minimum total being enforced right or a maximum total or you could apply some some discounts or something when line items of a certain amount are added and stuff like that and these business rules can only be guaranteed or assured if you're actually interacting with the aggregate and only with the aggregate the aggregate rules so there are a couple of things that are important here actually two things the first thing is that aggregate is sort of the thing that you refer to you also see that the arrows that I've put in here are always pointing to aggregates right they can point from an entity contained in an aggregate but they always point to aggregates and the other thing is the the scope of consistency so whenever you change something the scope of consistency is within within the aggregate right so if you add two line items to an order they're either added both or not at all all right so um like again looking at that stuff from from the implementation point of view in us let's say spring application or just any other application the difference between a normal entity and an aggregate is usually that for the aggregate roots I casually refer to them as aggregate but actually it's the aggregate root can be identified by an entity plus a repository right so going back to that just briefly to that example here in in the implementation for that project you have you probably have an address entity like classical JPA entity payment entity maybe even email entities because you want to like store them in the database and have multiple ones but you have only interact with with those through the customer and the according customer repository so there won't be a repository for line items but another one for order right and we actually the point I'm trying to get across is that we actually make a lot of use of exactly that additional information in the code base when we're building spring data rest but more on that later on an important thing the aggregates are the scope of consistency so whenever you again as I said whenever you change something you'd actually load the entity or the aggregate root from the through the repository access it and then yeah manipulate it and also again write it back right so usually transactional scopes is or transactional scopes are centered around aggregates in more monolithic applications you can often see manipulations of aggregates of multiple aggregates even within one transaction but if you're moving to more of a system of systems basically that consistency rule will actually be a very strong one here and I get back to that in a second when it comes to bounded contexts another thing and another aspect that I I mentioned is that you only refer to aggregates right you never refer to any entity it's not an aggregate root and that becomes that fact or that rule sort of becomes quite important again when it comes to to the building of rest api's on top of that so one thing I'd like to spend a minute on as well is that sometimes people get to stored in their in database thinking and that the thinking like as of their model as being something that's like written to the database in the first place so they're it's not that the persistence aspect is okay is the consequence of okay we're using a database but we have this database and now we have to extract a model from that right and actually extracting let's say JPA entities or something from a database is sort of the one of the most wrong things you can do in the first place and why is that if you look at this thing and imagine it's it's mapping on a on a database right then you probably like you're familiar with relational data databases I guess the relationship between the line item in the order is what it's a yeah it's a foreign key rate basically right I don't even care about it whether it's too many or or two one it's a foreign key right the relationship between the order and the customer is what a foreign key right so if you look at the the way that this thing is represented in the database there's absolutely no difference in the relationship between order and line item and order and customer however in the model in that model that I made up here there is right so I modeled these things as aggregates and there's definitely different relationships between the two and if you just extract your your domain model or try to extract your domain model because I'd argue if you do pull stuff out of your database only you're not going to end up with it with a domain model but just a giant sea of entities and that per se is not really bad but most people just like skip the necessary step of then looking at all that stuff and finding where are the aggregates and actually changing or tweaking the code accordingly alright so another quite important aspect in from the DDD book is the concept of a bounded context the the graphic I have here is a very entity driven way of representing our model here so we basically model our entities but just think about the order right if you're talking to a person that's working in the in the shipment or in the shipping department when it speaks of when that person speaks of an order its interested in a lot of way different things then if you let's say speak to someone in the department that's then responsible for invoices later on right so while the the shipment Department is only interested in like the actual shipping address and doesn't really care about the amount right it might be interested in the indy and the total of or the number of line items because by that the the shipment costs may be may be rising but it's totally not interested in what what is what the stuff in there actually costs whereas the the invoice department or the billing department couldn't even care less where that where that orders going to be shipped to but rather how much does that the bloody thing actually cost right so the bounded context is basically an is a concept in the from the book that sort of defines okay there's like there are these areas or these these contexts actually in which a term from the domain has a certain meaning and has a has a canonical meaning right so you're rather centering or trying to find these boundaries and try to build up your system or split up your system into these into these bounded context so that the the whenever you speak from an often order that that particular concept actually makes sense to the to the persons involved in that but in that in that bounded context all right so that's basically what you usually end up with an important aspect here and that will get important later on is that that usually needs to the fact that the customer is not something canonical anymore but it's something that's like sort of spread around the codebase right so and I've tried to what I try to make obvious here is that there's always one system that basically defines the identity of the customer so whenever you let have user an e-commerce system recently and registered with that system you usually get like guided through a series of steps in registration so you start putting in your name and your email address maybe in the first place so that's basically the user registration by that you basically you're you becoming a customer with an identity usually a user ID of something and then you in separate other steps you add your billing information you add your shipping addresses and whatnot and if you're looking closely at some of the shops are just like if you look at Amazon or something you can even realize that when you're adding editing this information you're not even talking to the same system depending on what information you're editing right so if you end your edit your payment information look closely the UI changes quite significantly they all just happen to look the same so that to the customer or to the user it basically looks like the very same system but effectively let's say the payment information that I'm adding is just only available in the payment or in the accounting system and these systems all refer to the one customer to the canonical thing through that thing that is actually defining the identity in the first place right so it's usually in in a rest world it's usually a URI right so the same thing applies to the catalog and oh Jesus and the references to those in in the orders right that all might also lead to even data to be duplicated let's say for for an order you might want to copy over some information of the product that you've ordered just for the very fact that like let's say I there's some description in the order there I want to in the product and I want to copy those into the orders because I don't necessarily want the the order to change when the when the product description changes so there's some data duplication going on even right all right the final thing on on the on the DVD side and basically on the on the foundation is the topic of domain events the first mature like you if you're talking about it in terms of a maturity level the first thing or the the first level basically is that your application code doesn't have any domain events at all right so you basically have classes that have getters and setters and all you do is you poke at those getters and setters and by that short sort of change the state of the application and you actually just change data right so the second thing is that you can instead of let's just poking at the data you could go ahead and make operations explicit there is this quote from I think Warren Vernon was it who who coined it in the first place whenever you like calling to setters in a row you're actually missing a concept right so you're doing something to that entity and you're doing it some in in some context and you're not making that explicit right so you basically it's usually then refactor into a separate method way then call this these two setters but why not make this an explicit operation on the entity right so instead of set address call it and make it a move right the customer moves from address to a to be that's so that that should be that should be an explicit operation the next thing that you can actually do is additionally to the state changes that you apply to your entities you can make sure that you capture important operations operations important to your business as events in some case right that might just like mean that I'm all that you that you just like persist an additional object to your database an event object that basically says okay this order was created at yada yada yada right so make those make those things explicit because then you can later on accrue those events per your database for those events right the extreme version of that is oh yeah so that's that's what I'm trying to get to important domain events should become like state transitions and that actually already maps to the to the rest world to some degree I go back in to come back to that in a second will you yeah okay let's let's skip that one or not skip but move that to later on the the third aspect is or the last aspect Jesus that thing is a bit quick here today the extreme form of the this this kind of event handling is called event sourcing or CQRS where you basically change the and be the way your application works entirely by only storing the events that happen to the system and then having a read model that basically replaced the events and then gives you the state of the system and and yeah so you basically reallocate that but that's usually it might be a step too far for some of the systems that are already already existing the point I'm trying to get across here it's basically a maturity level for explicitness of domain events right so we might bury those in just poking at data we might make them explicit we make might keep those as events or we might just like model or entire applications around them all right but get back to that in a second so what about the rest aspect um the first thing that I'm trying to or that we have to discuss is that I talk to a lot of people that just basically think that what a REST API is well we take our entities we just like turn them into JSON right so we flip the relational tables that we have we flip them by 90 degrees call that thing JSON and then throw that out to the public and then just say okay get to access things post to create things put to update things and delete for removing them the thing is that that might work for some cases and it might work for simple cases that however it doesn't mean that you can or even should try to solve all of your like or expose all of your domain logic like that fundamentally this is mapping back to the domain events level zero right we treat everything as data that we can just like poke at and change right there's no business operations being a becoming explicit the client doesn't really or has to somehow all of a sudden know when it's allowed to do what and yeah that's that's kind of a kind of a very very generic approach here but it comes with with a variety of downsides and we're gonna see a couple of more of them in in a bit the other problem with that okay we are exposing our database to the to the to the web is that that's not going to work really because if you like take the approach of like yeah you have just like a one-to-one mapping between your entities and your database tables you don't think about aggregates at all and that's basically what what usually those reverse engineering tools actually generate you get to a point where the entity could be related to another entity which could be related to another entity and yet another entity and when you then go ahead and try you take that or you create that spring mbc endpoint saying slash customer slash 47 11 and you take that customer instance read that from your database and then go to Jackson and say serialize that thing for me and Jackson just like looks at the Gators and oh there's this other entity and there's this other entity and there's this other entity and you end up with like like a megabyte of JSON with half the database basically pulled into the web because everything is sort of connected to everything if you're lucky enough then you have just like some circular dependencies or that thing goes boom right so the problem here is that we actually need to think about what the representation of our resources have to look like or should look like I couldn't I mean I'm quite a hyper media aficionado I couldn't even care less about what the URI actually looks like but that's ironically that's what most people start to think about when they're building api's these days but no the question is when I have a resource for a customer completely independent on what the URI locks what do I actually want to include and for whom and who actually gets control over over that design how can someone maybe include more properties or less properties what have you so that's a that's a very very very important question here and guess what by inspecting by moving away from just looking at the raw data and more looking at the model you can actually find great guidelines on how to actually structure the representations we see a bit of that so picking back up on on the on the like the DDD part here let's start with value objects not only are they a bit or bit a pain in the ass to to actually write to write them they also then again on the representation side of things need a lot of custom serializers that's a bit of an issue with let's say if you're working with jackson there is a bit of support just a side track and to segue to into the talk on spring that arrests we we have some code that a sort of allows you to just declare this this object here is a value object and then we will allow you to just define the way that it's supposed to be in the to look in the in the in the Jack in the JSON so basically customize Jackson for you so that you just say hey this is a value object and then Jackson does the right thing however again a bit more effort which might let you shy away from from using them don't do it value objects are great um the other thing is that okay here the these are the the like three are actually if you look at it more precisely it's it's actually two in here two aspects of aggregates that are nicely mapping into the way we we want to build a restful api is so aggregates are identifiable and by that they are actually referral that's why the first two aspects can actually be one and they are the scope of consistency which actually Maps nicely on to rest resources write rest resources are identifiable because they have a URI and they are the scope or they are a nice means to implement scopes of consistency basically because if that resource is the scope of consistency I can actually issue a put request and be done with it right so as soon as I have to sort of interact with multiple resources let's say two or three resources at once and want to create something as a whole right then the question comes up okay I mean I the first two requests actually worked the third didn't work any more how does how do actually like roll back the other two I'm not saying that this is like generally bad it just requires way more effort and if you can like get to model your resources that they support this pattern and they allow you to just like that or let the clients basically send some data and then create a even a more complex resource in the first place with with just one call it has a lot of lot of benefits here because like all the the other things are not going to matter them all right so one thing that and I think that I accidentally deleted slide here they're supposed to be a hyper media slide in the in between the two just like saying hyper media and what is what is hyper media all about and how does that actually help in terms of like building good restful api s well actually it doesn't really even even help building good restful api is because actually an api that's not using hyper media is not a rest api the idea the fundamental idea is that we're not only serving data so not only take the table and like flip that by 90 degrees throw that at the client but we also tell the client or send the client information that it can use to actually do something with the data it can find out what to do next basically with that thing and that's where the hey TOS hypermedia is the engine of application state comes in because a hyper media driven client would go ahead like inspect the hyper media elements and then act accordingly and that's basically the mechanism of how you how you'd like yeah basically do that that's it how do you implement hyper media exactly that way but what what does that mean so assuming we're we have these two options right we sent just like plain JSON to the client or we send JSON and some links to the client doesn't that make the client more complex that's a question we might might have to answer and the other question what benefits to actually get from doing that why would I want to do that in the first place right so what we're basically doing by that and I'm going to like to go into into a bit more detail of that because um it's a pretty important point here is that we're trading two different complexities within with each other basically right so on the one hand we have domain complexity business rules and stuff like that and on the other hand we have protocol complexity or that's what I call it it's basically the client having to understand ah this is not only Jason but a special kind of Jason that has links in them and those links are telling me something and I have to understand these links right so that's the protocol complexity it's got nothing to do with your with your domain so let's say you have a non hyper media based system so the simple just like throwing Jason at the client and the client doing something with it that means the amount of the main knowledge is very high in the client right so the client has to know URI structures it has to know where to do the calls right not only a single URI but basically every URI that's that's in available on the server-side system it also has to know about the semantics of the field so it not only has to know that there is a field let's say for for a system where you take orders it doesn't only have to know there is an order status in the in the in the in the Jason and I can just display that it also has to interpret the status by looking at the value and then saying okay if the status is X then du Y right so it has domain knowledge very very fundamental domain knowledge it doesn't have a lot of protocol complexity just to have to know Jason that's basically it right and that that basically leads to the fact that there's a strong coupling to the server meaning that whenever those business rules change let's say the like the status of the with with the steps of the order whenever when can I actually pay the order right in a certain status only so let's say on the on the left side of that field here the client would inspect that status field and then display a button saying check out right so if you now go ahead and move away from putting all that domain knowledge into the into the client and rather move to the other side so teach the client more protocol knowledge and by that be able to remove the domain knowledge or a lot of the domain knowledge then you can lower the coupling between the two systems and why why is that Amin what is actually causing that I mean the the issue here being why do we want low coupling in the first place let's say if you have a microservices based system everyone is building micro services these days right you have a server system and you want to only have four clients maybe and you want to change something to the API in the API you want to do it implement a change and you want to deploy that change right and it's maybe it's a breaking change right so then you have to redeploy all the four clients as well and you basically created in a coupling between the systems in terms of deployment and if you change those systems again you have another another set of clients yada yada yada and you basically get to a distributed monolith because you have to orchestrate either orchestrated deployments or you have to create new versions what people call versions of API is which usually are just you api's to work around that right so you create some kind of effort you create you create the need for for communication between the teams which is actually something that you want to avoid with micro services right so you you just want to deploy new versions of your software like continuously and if you can decrease the coupling between the system that's that's actually a good thing here right so yeah one thing here is that you want to be able to change the api's or involve them if you run it have a system of systems basically give me a let me give you a quick example here again this is the that I just mentioned you have the order right it has a status fields payment expected and the client is not let's say we stay on the on the left side of the other spectrum that I just made up and we're we're not only like treating that thing as data but Jesus we're not only treating that as data but also inspect the field for for the decision whether we want to actually when we actually pay the not pay the but display the checkout button then we go ahead and inspect that field right so there's nothing wrong with that except for when business on the server side now all of a sudden decides we have a new requirement right so all user facing text should be internationalized and that basically means damn it if we implement that we break all our clients and that's a bad thing right so what could be the solution to just that yeah well let the client UM not actually not actually use the status field for for for that decision but just look at the links that you put into the representation I'd say you have a payment link there or in this case a a cancer link and only let the client that go ahead and basically say whenever that cancel link is present in the representation I built a I show up the show the yeah cancel order button or I show the checkout button or what have you and it's not really touching all the other data but only making use of it for for displaying purposes what we're actually doing here is we're reducing net was did the tasks of the exercise we're reducing the domain knowledge of the client and moving it to more protocol knowledge and basically we're able to sort of change the we keep the order the complexity of a business rule on the client and the only thing that a client has to do is basically is the link there is the link not there right right so the thing is um what has this stuff to do with with DDD you might ask right the thing is that by doing that we're actually doing something that's a core aspect of DDD which is making things explicit right you're not like sending a JSON and then you have a status in there and then the client basically decides when to when to display the button based on that on the data that is in there but there is an explicit link in there that basically tells the client now you are allowed to actually check out or now you're not a very interest or very important topic in that area is security right just imagine the client having to find out whether it's allowed to do actually those two things or let's say display a cancel order button maybe only users with the certain privileges are allowed to do that right in a non hyper media based system a client has to go ahead and then see okay there is this cancel order functionality and now I have this user account and now I have to somehow check go ahead and check whether the user has some permissions again with a server called the API and if that returns true then I can actually display the button none of this is necessary if you just like go the hypermedia route because if the user the client just says on behalf of the user show me the order and the server basically detects oh this is user X he's not allowed to actually cancel that order I just don't send the link right that doesn't mean the server doesn't have to check that the server might not like the client might not issue that request in the first place but again the client is completely free of in this case not completely free but it doesn't have to actually bother with whether is this action allowed or is this action not allowed at all right so that's that's a fundamental thing that actually what at the point in time when I realized this when when I started like putting these state transitions into into my into my representations or these links to trigger these state transitions you really start to see okay there's this connection between okay this is this important domain event that I want to want to or have to basically expose to my clients let my clients trigger that domain event and I need to make that explicit right I don't want to I don't want the client to just like patch or issue patch requests and my to my resources but I want to offer it it it guidance to to actually do things right comingcoming be coming back to that in a second um another aspect in in the general like procedure is one that for a lot of things technological things that might not be obvious in the first place that you use on the back end when you just like right server code right so basically you have your entities you have your repositories you have your services you just like interact with them and just like invoke operations on them store them back to the database yada yada yada there are a couple of implicit technical concepts that we also got so used to that we might just not think about them when we throw or try to create a rest arrest API on top of those um and one of them is like I did I mean the first thing on what Matt the point I'm trying to get across is that you should be aware of those and you should make sure that you actually translate the concepts for which HTTP has a solution for into actually that solution right so the first thing is that I mean that's more of a pattern here but what we're actually doing with it says bring to the rest or what what people do when they just implement rest resources using spring MVC they usually use this collection resource item resource pattern so you have a resource that serves all of the customers and you have a resource that serves individual customers right that map's nicely on to our spring data repository pattern so in the repository usually have methods to either access all of the entities or pageant it threw them yada-yada-yada um a very important thing in in spring that arrests basically yes and if you're interested in to learn more about it I encourage you to come to the talk on Thursday is that we can actually look at the relationships between the entities and the aggregate roots and in the representation design we can cut off the the places where you actually point to another aggregate right remember that that order line item customer example right so we have the orders with the line items embedded and the customer being something separate again so we have different kinds of relationships right and it's it's a good idea to just go ahead and say okay within that aggregate I just include everything in my representation so when I look up the order I basically get the order some order information and then all line items nested in an adjacent structure but as the customer is a new as a separate aggregate right it has a separate consistency like a separate life cycle we actually shouldn't include it because that when we will issue a put request to the order would raise the question okay we're now manipulating to aggregates at once is that what we really want I mean conceptually if you like have an order that said and the customer is embedded and let's say you get a request that changes the customers name like when you update the order is that we need like does that make sense even right do you want to change the customers name when you update the order I guess not right so it's more the the customers is a related thing so use the concept that the web actually exposes for pointing to things which is links right so instead of embedding the customer you'd go ahead and yeah have a link saying by the way the customer lives over there oh yeah one of my favorites usually entities by the virtue of the fact that they're persisted to the database carry an artificial property the identifier property right however if you really think about it and ID is not really a domain concept right if you're a customer at a shop you you're probably in their IT systems have an ID but first of all you're just a customer and the issue with that is that like if they have seen a couple of cysts or technologies that when they expose or try differently the same thing basically as we do with spring that arrest they expose the identifiers property to or put that into the JS into the JSON document and I think this is fundamentally wrong because HTTP just has a it has a concept of identifying things right you arise unique resource identifiers it basically says this is the thing that identifies customer with the customer which in our back-end system maybe the customer 47:11 but on the protocol level the ID 47:11 doesn't really do anything we need a URI right and the problem with exposing the IDS inside in the body is basically that you create ambiguity right so if I update cut the issue in a put request to customer 4711 that contains an ID with 47:12 what am I supposed to do as a server do I actually change the ID of 4711 to 47:12 No so having multiple multiple IDs or identification schemes around flying around this is usually a bit of a brittle thing and avoid that so that's why it let's say it's spring that arrests for example it basically removes that property from from the representation because for the client that property shouldn't actually matter at all which has to refer to things through the you are eyes right the same applies to optimistic locking and diversion properties HTTP is a concept for that that's an e-tag right so if it's basically a hash over the representation a hash over the state so for all the aggregates the the add version annotation or the add version version field can or should be translated into into an e-tag again this is what's bringing arrest does out-of-the-box for you but even when you're just like hand-coding that stuff that's that's definitely I think to would be a thing to do here a good thing to do and the same applies to last modified properties why is that a good idea in the first place to expose those properties as headers because it allows certain mechanisms of HTTP to just work out of the box right I guess you've heard of conditional requests so with a get request you can for example say if non-match send a set a header with if non match with let's say an e-tag which basically expresses their server only give me the customer in case it's not matching the eTech here's the hash right so and that the server can actually then then use and say okay this thing hasn't changed at all I don't need to waste any bandwidth to send you that stuff so you can by translating those concepts into the HTTP appropriate ones you can actually make sure the infrastructure can use these concepts all right so a rounding things off there is a sample project that I started quite a while ago that sort of implements all of the stuff that I just mentioned like I try to do to like it use value objects in throughout the codebase so try to be a good ddd citizen here but even more importantly and then show you how to build a nice restful api that also does all the things that that I just like to scribe on top of it it's basically the implement the the sample is the the sample as a concept is taken from a book called what is it restful restful web services with O'Reilly from Ian Weber Ian Robinson Jim Weber and savage para studies I probably totally reqtest his last name and it has a strong focus on hyper media so highly recommended read it basically is a model Starbucks Coffee ordering experience as a rest web service I like it quite a bit because it has in my mind it has the the right the right balance between being a very simple and understandable sample but at the same time having quite quite a few interesting aspects of restful api is that some very simplistic examples usually don't have some of them being that's basically the state chart of the of the order that processes through the through the system so you basically place the order it's it's in the payment expected state then in which you can update it right you can then pay it that's the step four you could cancel the order while it's in payment expected state when it's while it's preparing it's basically issuing a server-side server-side here's some long-running threat it's basically a threat sleep of twenty seconds so pretty close to what Starbucks employees usually do it's then ready at some point and then there's another request that you have to issue to complete that thing and it raises a I mean if you just model that thing that naively and the way that like usually like these API development tools like work it's like you wonder or you do you think about duis in the first place right this is important no it's not really so you you basically get away from that here and the problem being you hard-code these URI patterns into the client they might change you cannot really implement how do you actually implement that or how do you actually guide the client that it can only only issue the delete request to cancel the order if it's a payment expected say right that's something the client has to do it has to it creates incentive to do exactly the wrong thing right baking hard-coding euchre your eyes and inspecting the payloads for for for to to make business decisions right if you go ahead move away from that and rather say okay I make this entire thing link-based or hypermedia based I basically go ahead we introduce like state transitions so that it basically becomes explicit when a certain transition is allowed right we just like introduce link names there and then that sort of if you just document that no client whatever uh no client developer would ever get the idea to try to interpret some of the payloads except looking at the links and saying okay when I found this cancel link I can issue let's say a delete request to that resource that is linked to yada yada yada right right so there's a spring implementation as I said that that it's built on spring that arrests and also there's a bit of manual implementation code that just like shows that spring that arrest is quite extensible if you want to see more of that in my please come to my talk on on the topic in on Thursday maybe one one aspect that I'd like to get get across here so far I spoke about or the primary aspect of that all of that hypermedia dance being to lower the coupling between the server and the client so that we can get a bit of leg room in the server side implementation to change things right and another aspect that actually comes comes in quite handy often is that with that style of API integration or implementation you can in some cases even get the client to to pickup functionality that it wasn't even expecting in the first place let me give you an example of that let's go back to that thing oh Jesus it was too far let's go back to that thing here the state diagram states are basically says we can only cancel the order if it's in payment expected state right that's kind of unusual that's not really how Starbucks work if you don't like your drink or they I mean you're just some some unsatisfied are just not accepting it you can still cancel it later on right so if you implement the client in a way that it says if the cancel link is present I display the cancel order button to actually cancel the order then business could even go ahead and later on say hmmm well or the server site could actually go ahead and say well so far we only displayed the canceling in that particular state payment expected but why not just like sending out that link adding that link also later on right while it's in preparation also before if the even if the if the drink has always already been prepared and you can just like add a new link on the server side and if the client build is built in a proper way it will just actually just like be able to cancel the orders later on right even if it wasn't designed with that in mind in the first place so you get quite a if you basically move all of the business logic you keep the business logic more on the server and that usually is is it is a good thing because I mean yeah you just like have to otherwise you have to re-implement that logic both on the server and on the client which just creates that that's wrong coupling just like a couple of pointers in case we you're looking at and decide not to come to the session on Thursday and and one look at the sample as well something we often get criticized for is that it like with the spring that arrests implementation is that people say okay you well what I don't like about that is you take your doing the domain classes the entities and you turn them into JSON so there is a there's a strong coupling like between like the API and the Dawei model si yes there is because what I mean what's the point of like not doing it right if there's a first name property you might want to expose the first name property plus you can like tweak the mapping through the mapping library right there is Jackson in place you can like reg mix-ins you can register custom serializers and they would all be just like realized just imagine us public publishing a framework where for every entity you have to create a domain class with the exact same properties but that i mean we probably would have been gotten bashed much much worse for that so there is a mapping step that's what I'm trying to get across here and there should be so it's I think it's totally fine to start with with like the like sort of the structure that you have in your domain model because I mean that's if it's the core of the of your domain well yeah I had to get the the argument here however if you there's there's important bits you need to take care of thinking about the representation design and in case you want to want to tweak things use the mapping library capabilities of that there's a dedicated class called Jackson customizations in that example that has all of the Jackson customizations there are a couple of them in there like for four dates and four I think quantities and stuff like that yeah also an important part I get to that in the in the other talk in much more detail don't try to over use like it say in this case bring that arrest if it doesn't like work because of like the the business logic is too complex and you don't that that clock model doesn't really fit don't try to make your domain model or your operations to fit the crowd model and also don't try to bend trend data rest there's like a couple of connection points where you can just like go ahead implement your own spring MVC controller for just that part of the functionality and then integrate that with all the the API that spring that arrests actually exposes yeah the resource processor in if there's a couple of them it's an SPI interface where you basically can can tweak the links and that's the the primary places to look at if you want to see how these links are basically put into the into the representation but yeah alright so that's a couple of resources there's the the project in my in my github account I sort of wrote down the five minute elevator pitch for hypermedia and the consequence of API evolvability in a blog post so if you want to share that with colleagues there's that and that leaves me five minutes for questions if there are any go ahead mm-hmm yeah well I mean if so the question is uh there's like a he was talking about a secure s based systems system and how would these state transitions map to to to these secrets commands down like wouldn't a state transition via a command to the to the to yep mm-hmm mm-hmm mmm-hmm oh I think I see what you're heading for so the question is if you if you treat these things individually as a command right how do you actually like then put the state back into the reefs in the end of the representation so I the the example doesn't have that implemented as CQRS system but just like a as an ordinary ordinary just like implementing it's basically on the on the even of the on the first level only of the maturity event majority model that I made up so we basically just have operations on the entities and actually there is like for for these not not all of these steps actually refer to individual resources so there's still the order resource and the order resource is basically inspecting the state and it's basically them getting back to your read model sort of inspecting the state and then adding those links so of course the server implementation has to look at the fields and say at the status basically right but this is okay because that's the server process and it's self-contained so it's basically deciding when that order status field of the order is there then I put in the link into the representation it's just that I want to avoid exactly that logic to be duplicated on the client that's that's the whole point actually and I think you should you should be able to just like copy like copy that approach to a secure space systems big system because all we're doing is basically take the current take the current state of the order and basically translate that into a representation and by that we're in that step we actually add links based on the state of of that thing and I mean you have this probably this this short consistency gap here but even if the if the client if let's say that state doesn't really propagate immediately to the to the to the read model then the client would just like see for a tiny second for one request it wouldn't see any any other links so it would just not do anything to it and then maybe just like refresh a moment later and then get the correct state again so that's kind of one question yeah yeah yeah so that the question is like that seems to that all of that stuff seems to make sense for human to machine interaction which is quite obvious because all most of that stuff is basically derived from how the web works right but does that really work for for machine to machine communication and the second question was should we have like the the concept of or the the an implementation of the very same aggregate on the client so actually the for the first question I'd argue it shouldn't actually make too much difference whether it's like a it's a human being I mean when we browse to Amazon to the website we look at the link name and then we pull out semantics from that for machine to machine communication you of course have to find means to define the semantics of what does payment the payment link actually mean right it's like that can be documented that can be even like machine consumable you might wanna I mean you can take that to the extreme of course but I'd argue that the fundamental benefits of in terms of reduced reducing the coupling are already given if you just like even if your hard code that knowledge into the client that that hypermedia approach already gives you a lot or on that path so I think that that still makes sense the other thing is that you can of course go ahead and basically like on the client I mean let me start the other way around first as I said we're moving to more protocol complexity on the client which where I see a lot of still of a lot of room for improvements in terms of supporting libraries and stuff like that there already are libraries around that support teach and a lot of hyper media based media types like how collection Jason Styron we're also doing a lot of stuff there in in spring Haiti us there's a quite a big change coming with a prototype for more affordances therefore for other media types and in for instance model when it comes to the to the the representation of the domain of the aggregate you of course can do that because it just like might make the the implementation of the other client code easier right if you can just like half code that you say is canceled the crucial thing I'd say is that you then for those for the implementation of those is canceled methods you'd have to resort on the presence of the links so I mean I can imagine that that that's somehow like you could make this generic in terms of like in is payment was payable or something and then just inspect whether there's a link relation of the same name but you basically have to go ahead and use the the means that the protocol basically gives you there yeah but that's it all right one more maybe is that okay let me let's take one more question I take the other ones offline if that's okay go you in mm-hmm yeah can repeat the last part the last sentence how would you yes yeah oh okay so the question is if we remove the IDS from the representation like the backend IDs how do you actually refer to the let's say you have an embedded collection of other entities right how do you actually refer to the individual instances and that's a good point and that's a crucial point as usually the the most type of media types that fly around like with Jason probably being the most prominent one they rely on the order of the items so when you say you have line items and you have 10 in 10 in there you just rely on the fact that the first item is the first item and they're just like maps to the to the server side so it I think you of course you can you can sort of loosen that that that constrain a bit when it comes to embedded embedded documents because I think that the problem of like having multiple IDs or the the case of the ambiguity right between the ID that's in the document and the URI is is not even given for nested documents so it's not so much of a problem so just you might want to keep them in there but as a default I was kind of thinking okay or saying that don't try to to transport other forms of identification like out of your system right because in generally in in general that you're using a long as also incremented long in the database shouldn't even the client shouldn't even bother write it why does it why does it have to know in the first place yeah that's that's the issue okay so thanks for taking the time would be glad to see some of you back on Thursday but for now enjoy the rest of the day and the conference in general thank you
Info
Channel: SpringDeveloper
Views: 126,691
Rating: 4.8217821 out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, spring cloud, domain driven design, REST, microservices
Id: NdZqeAAIHzc
Channel Id: undefined
Length: 75min 15sec (4515 seconds)
Published: Tue Nov 15 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.