Update an entity inside an aggregate - orm

I was reading a similar question on SO: How update an entity inside Aggregate, but I'm still not sure how a user interface should interact with entities inside an aggregate.
Let's say I have a User, with a bunch of Addresses. User is the aggregate root, while Address only exists within the aggregate.
On a web inteface, a user can edit his addresses. Basically, what happens is:
The user sees a list of addresses on its web interface
He clicks on an address, and gets redirected to this page: edit-address?user=1&address=2
On this page, he gets a form where he can modify this address.
I we decided to bypass the aggregate root, this would be straightforward:
We would directly load the Address with its Id
We would update it, then save it
Because we want to do it the DDD way, we have different solutions:
Either we ask the User to get this Address by Id:
address = user.getAddress(id);
address.setPostCode("12345");
address.setCity("New York");
em.persist(user);
The problem with this approach is, IMO, that the aggregate root still doesn't have much more control over what's done with the address. It just returns a reference to it, so that's not much different from bypassing the aggregate.
Or we tell the aggregate to update an existing address:
user.updateAddress(id, "12345", "New York");
em.persist(user);
Now the aggregate has control over what's done with this address, and can take any necessary action that goes with updating an address.
Or we treat the Address as a value object, and we don't update our Address, but rather delete it and recreate it:
user.removeAddress(id);
address = new Address();
address.setPostCode("12345");
address.setCity("New York");
user.addAddress(address);
em.persist(user);
This last solution looks elegant, but means that an Address cannot be an Entity. Then, what if it needs to be treated as an entity, for example because another business object within the aggregate has a reference to it?
I'm pretty sure I'm missing something here to correctly understand the aggregate concept and how it's used in real life examples, so please don't hesitate to give your comments!

No, you're not missing anything - in most cases the best option would be number 2 (although I'd call that method changeAddress instead of updateAdress - update seems so not-DDD) and that's regardless whether an address is an Entity or Value Object. With Ubiquitous Language you'd rather say that User changed his address, so that's exactly how you should model it - it's the changeAddress method that gets to decide whether update properties (if Address is an Entity) or assign completely new object (when it's VO).
The following sample code assumes the most common scenario - Address as VO:
public void ChangeAddress(AddressParams addressParams)
{
// here we might include some validation
address = new Address(addressParams);
// here we might include additional actions related with changing address
// for example marking user as required to confirm address before
// next billing
}
What is important in this sample, is that once Address is created, it is considered valid - there can be no invalid Address object in your aggregate. Bare in mind however, that whether you should follow this sample or not depends on your actual domain - there's no one path to follow. This one is the most common one though.
And yes, you should always perform operations on your entities by traversing through aggregate root - the reason for this was given in many answers on SO (for example in this Basic Aggregate Question).
Whether something is an entity or VO depends on the requirements and your domain. Most of the time address is just a Value Object, because there's no difference between two addresses with the same values and addresses tend to not change during their lifetime. But again, that's most of the time and depends on domain you're modeling.
Another example - for most of the domains a Money would be a Value Object - 10$ is 10$, it has no identity besides amount. However if you'd model a domain that deals with money on a level of bills, each bill would have its own identity (expressed with a unique number of some sort) thus it would be an Entity.

Related

Filtering user access based on tabled responses

I am building a "Survey" type application. The user answers a set of questions with pre-vetted answers.
Question: Where do you live?
Answers: England, Finland, Spain, France, Monrovia
The answers in this case would be in a DropDownList.
Once the user has completed the basic responses (location, age, sex etc) I would like to be able to prevent them accessing the rest of the survey based on their answers.
So for example, if they live anywhere but England I want to direct them to a page which says "Thanks, but Monrovian's can't complete this survey". I need my filtering to be user configurable (Table based) and I need to be able to have ANDs and ORs.
So one filter being the user MUST earn 100k+ a year.
Another being they must either live in Spain, or be female AND like model trains - "100k+ && (Spain || (Female && Trains))"
I would usually use Enums and bitmasking for this, but as my country list is 200+ items long, I can't think of a sensible way to store the filtering.
Hopefully I have made some sense and someone has a decent solution :)
I don't know if I can answer your question completely, but I'll try...
So, we have a bunch of Views that are only visible to the user if she previously chose some answers, like, she will see view#3 if she is older that 30, and view#4 if she is younger than 30 AND from China, and view#5 if she is older than 40 AND from Spain OR Italy, and so on...I want also to introduce the notion of **step**, and for each step we could have 1, 2, or more corresponding views. Each view should have a set of rules (like the ones above) that define if it is displayed or not.
How to create these rules? These rules could be simple instances of a Filter class/interface that, when asked, should return true/false. Like this:
interface Filter {
boolean apply();
}
Then you can create Filters like 'older than 30', 'from Spain', whatever. Remember that each view is configured with a set of rules (Filters) so it can answer yes/no if asked if it can display itself.
Next, how to apply these filters?
We could have a controller object that only knows about **steps** (each step can have one or more corresponding views, as I said), and, after the user pressed **next** at the current step, it should collect the answers and apply them against the rules attached to each view. Like, take the answers from step one, and apply them to all views from step two, and see which one matches (returns true). For example, at step two, you can have two separate views, one for young people, other for old people, and you apply the rules from each view to decide if you show the old or young view.
I could give you one code example, and you could also do research on your own, since I know nothing about your technical environment. I have used Google Guava's predicates on a similar problem and here it is: suppose we are dealing with Witch objects, and each of them has name(string), age(int) and spells(collection) attributes. If I have a list of witches and I need to sort them based on specific criteria, I can do:
// first I want to sort witches by age(natural ordering) then by spells,
// and then by name lexicographically
Ordering.natural()
.compound(new BySpellsWitchOrdering())
.compound(new ByNameWitchOrdering())
.sortedCopy(witchList);
The above line of code is going to take the witch list and return a list of sorted witches according to the criteria. Your situation is pretty similar.
Next, how to create the answers? For each view(page), you have possible answers, like, for view#1, you can have : age, sex, race, country. You can construct some answers, in the form of strings, ints, enums, and pass them to the controller, which in turn is going to apply them to each view corresponding to the next step.
As for how to store the rules in the database, as an example, you could have a column defining rule name (like, OLDER THAN) and one column for value, say, 30. Again, I do not know that much about your environment, and it is a really general issue, so I will stop here...

How to structure REST resource hierarchy?

I'm new to server side web development and recently I've been reading a lot about implementing RESTful API's. One aspect of REST API's that I'm still stuck on is how to go about structuring the URI hierarchy that identifies resources that the client can interact with. Specifically I'm stuck on deciding how detailed to make the hierarchy and what to do in the case of resources being composed of other resource types.
Here's an example that hopefully will show what I mean. Imagine we have a web service that lets users buy products from other users. So in this simple case, there are two top level resources users and products. Here's how I began to structure the URI hierarchy,
For users:
/users
/{id}
/location
/about
/name
/seller_rating
/bought
/sold
For products:
/products
/{id}
/name
/category
/description
/keywords
/buyer
/seller
In both of these cases objects in each hierarchy reference a subset of the objects in the other hierarchy. For example /users/{id}/bought is a list of the products that some user has bought, which is a subset of /products. Also, /products/{id}/seller references the user that sold a specific product.
Since these URI's reference other objects, or subsets of other objects, should the API support things like this: /users/{id}/bought/id/description and /products/{id}/buyer/location? Because if those types of URI's are supported, what's to stop something like this /users/{id}/bought/{id}/buyer/bought/{id}/seller/name, or something equally convoluted? Also, in this case, how would you handle routing since the router in the server would have to interpret URI's of arbitrary length?
The goal is to build convenient resource identifiers, don't try to cross-reference everything. You don't have to repeat your database relations in URL representation :)
Links like /product/{id}/buyer should never exist, because there already is identifier for that resource: /user/{id}
Although it's ok to have /product/{id}/buyers-list because list of buyers is a property of product that does not exist in other contexts.
You should think of it in a CRUD fashion, where each entity supports Create, Read, Update, and Delete (typically using GET, POST, PUT, and DELETE HTTP verbs respectively).
This means that your endpoints will typically only go one level deep. For instance
Users
GET /users - Return a list of all users (you may not want to make this publically available)
GET /users/:id - Return the user with that id
POST /users - Create a new user. Return a 201 Status Code and the newly created id (if you want)
PUT /users/:id - Update the user with that id
DELETE /users/:id - Delete the user with that id
Going into more detail, such as /users/:id/about is likely not necessary. While it may work, it may be getting slightly overspecific.
Perhaps in your case you could add in:
GET /users/:id/bought - Array of products that the user bought
GET /users/:id/sold - Array of products that the user sold
where you could return a list of id's (which can be fetched through the products API), or you could populate the Products before sending them back if you wish. If you do choose to populate them, you probably should not then populate users referenced by each product. This will lead to circular includes and is wrong.
And for Products, in your sitation I would use:
GET /products- Return a list of all products
GET /products/:id - Return the products with that id
POST /products- Create a new product. Return a 201 Status Code and the newly created id (if you want)
PUT /products/:id - Update the product with that id
DELETE /products/:id - Delete the product with that id
GET /products/:id/buyers - Array of who bought the product
GET /products/:id/sellers - Array of everyone selling the product

How to design RESTful URL with many input parameters

I am working to create a Java based RESTful API that uses Spring MVC.
Now for some of the API endpoints-- multiple different parameters are required... I am not talking about a list of values-- more like parameter1, parameter2, parameter3, parameter4 and so on-- where all the 4 (or more) parameters are of different data types as well.
How do I design the API endpoint URL for the above scenario, eg for 4 separate input parameters? Is there any recommended way/best practice for doing this? Or do I simply concatenate the 4 values, with ach pair of values separated by a delimiter like "/"?
EDIT from user comment:
Example: I have to retrieve a custom object(a 'file') based on 4 input parameters--(Integer) userid, (Integer) fileid, (String) type, and (String) usertype. Should I simply create a REST Endpoint like "getfile/{userid}/{fileid}/{type}/{usertype}-- or is there a better (or recommended way) to construct such REST endpoints?
In REST start by thinking about the resource and coming up with immutable permalinks (doesn't change)to identify that resource.
So, in your example (in comment), you said you want to retrieve a file resource for a user and type (file type or user type?)
So, start with just enough information to identify the resource. If the id is unique, then this is enough to identify the resource regardless of the user who owns the file:
/files/{fileId}
That's also important as the url if a file could change owners - remember we want to identify the resource with just the components needed so it can be a permalink.
You could also list the files for a specific user:
/users/{userId}/files/
The response would contain a list of files and each of those items in the list would contain links to the files (/files/{fileId})
If for some reason the file id is not unique but is unique only in the context of a user (files don't change owners and id increments within a user - wierd) then you would need these components to identify the resource:
/users/{userId}/files/{fileId}
Also note the order based on the description. In that wierd case, we said the files are logically contained and IDed by the user and that's also the containment in the url structure.
Hope that helps.
A GET request to file/{usertype}/{user}/{type}/{fileid} sounds good

Is there a "uniqueID" type property for address book contacts?

I'm making a game involving the user's contacts, but need a way to uniquely identify each contact. This is because the user can easily change the name, phone number, or other property of a given contact. Is there a way to do this?
You can use ABRecordGetRecordID() to get the unique ID of a record. It returns an ABRecordID which is a typedef for int32_t.
ABRecordGetRecordID() is the API that you can use. However, apple documentation does states some noteworthy points about the ABRecordID returned by this API.
Every record in the Address Book database has a unique record identifier. This identifier always refers to the same record, unless that record is deleted or the data is reset. Record identifiers can be safely passed between threads. They are not guaranteed to remain the same across devices.
The suggested method as per apple guidelines is
The recommended way to keep a long-term reference to a particular record is to store the first and last name, or a hash of the first and last name, in addition to the identifier. When you look up a record by ID, compare the record’s name to your stored name. If they don’t match, use the stored name to find the record, and store the new ID for the record.
In my app, I am also checking for creation date of the contact since the name against the ABRecordID could have been changed by the user. Creation date of a contact DOES NOT change upon device reset.
Though I have pasted most of the content here, its always advised to read the documentation

WCF data services - Limiting related objects returned based on critera

I have an object graph consisting of a base employee object, and a set of related message objects.
I am able to return the employee objects based on search criteria on the employee properties (eg team) etc. However, if I expand on the messages, I get the full collection of messages back. I would like to be able to either take the top n messages (i.e. restrict to 10 most recent) or ideally use a date range on the message objects to limit how many are brought back.
So far I have not been able to figure out a way of doing this:
I get an error if I attempt to filter on properties on the message (&$filter=employee/message/StartDate gives an error ">No property 'StartDate' exists in type 'System.Data.Objects.DataClasses.EntityCollection`1).
Attempting to use Top on the message related object doesn't work either.
I have also tried using a WebGet extension that takes a string list of employee IDs. That works until the list gets too long, and then fails due to the URL getting too long (it might be possible to setup a paging mechanism on this approach)...
Unfortunately the UI control I am using requires the data to be in a fairly specific hierarchical shape, so I can't easily come at this from starting on the message side and working backwards.
Outside of making multiple calls does anyone know of a method to accomplish this with wcf data services?
Thanks!
M.
Looks like the only real way of doing this is in fact to reverse the direction of the query.
So instead of starting from the Employee, I go from the message side. You can filter back on the employee properties, and restrict on the Messages collection. Its not ideal, as it means iterating the collection on return to re-center it on the employee for what I am attempting to do, but it will work. The async nature of silverlight and rich client at least means while an extra iteration is required, it still appears to be reasonably fast.
Another interesting thing to note: the current version of odata/wcf data services does not support querying on properties of inherited classes, so I had to move the start/end date properties up to the base class in order to be able to restrict my search on them.
http://Site/Service.svc/Messages()?&$filter=Employee/OfficeName eq 'Toronto' and (year(StartDate) eq 2010 and month(StartDate) ge 9 )