When designing a RESTful API should resources which are dependent on others be modeled as sub-uris or should they simply reference each other?
E.g. presuming a door is always dependent on a house then
/house/73/door/1
or
/house/73
/door/1044
where house and door include references to each other?
Most RESTful APIs I have found are quite flat so I would value references to any which do have more complex relationship dependencies.
Regards
In UML terms, if the relationship is that of Aggregation, then you use a flat hierarchy with links between things, whereas if the relationship is that of Composition (i.e., the lifetime of a door is strictly bounded by the lifetime of a house) you use sub-resources.
I'm not suggesting drawing a UML diagram! But it does help to have in mind that distinction. (You could also model the Aggregation case by having sub-resources that are just redirect to the real ones; redirects are RESTful. OTOH, I don't actually like doing that; I prefer to make any relationships explicit and to keep the number of redirects down.)
Just remember that URIs are an implementation detail of the server. If you can model them as flat resources then do so. It will be easier for the server to handle them.
If the identifier for the door is not unique across all houses, then your server is going to need to know the house and therefore you need to include the house in the URI.
The relationships between the resources should be modeled by links within the returned representations. i.e. Your house representation should probably contain links to all of the door resources in that house. I would recommend trying to avoid using the URL structure as having some domain meaning.
Only use a hierarchy if it is needed to uniquely identify the resource.
Related
I have looked at this PUT vs POST question and others on stackoverflow and after going through the answers I found out:
Use POST if server identifies the address of the resource
Use PUT if client know the address of the resource.
Now above works fine if I have a single independent entity. For example if I have Student entity I am admitting a new student to schools I might create a REST endpoint as /api/schools/schools-name/student with POST HTTP method. But once the student has been admitted and I have to make changes to this student I can use Patch/PUT.
But In my case I have dependent entities that is parent and child. First I create parent entity using the POST. Now the child entity is created only after parent entity has been created. Why they can't be created together like after parent entity is created, create the child entity also, is because of business requirement.
Important points to note are that parent and child entity are linked by an id column only. So currently my url for creating child entity is /api/entities/parent-entity-id. Also there is no request body while creating the child entity as all the required info for creating is stored in parent entity.
My question is that should this method be POST as we are creating the
child entity or PUT as I am updating the children of the parent
entity which already has been created?
As mentioned in the question there is no request body for creating a child entity. This api is just to trigger the child entity creation. Parent entity already has all the info.
If you are sending an unsafe request to the server, and it doesn't match the semantics of any of the other HTTP methods, then you should use POST.
In particular, if the message-body is not a candidate representation for the resource identified by the target-uri, then PUT is out of bounds.
The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload
First and foremost, REST is an architecture style used if you need decoupling of clients from servers to allow evolving the server side without risking clients to break. REST isn't a toolset you pick the most suitable things out and leave out the remainder. It is more of an either apply all of the steps and constraints REST proposes or you wont benefit from it thing! For simple back- to frontend communication it is probably to much effort as you are usually in control of both ends, however, if you aren't in control of one end only then you might gain the most benefit of such a design actually.
REST relies heavily on standardized protocols and media types. The interaction model is very similar to the browsable Web, the big cousin of REST. Therefore, the same concepts that apply to the Web also apply to REST. The core idea in both should always be that the server teaches the client on how to do things while clients only take what they are given without trying to deduce further knowledge from either previous interaction or analysis of URIs or the like. I.e. on the Web, HTML forms are used to allow clients to enter certain input that is sent to the server upon clicking a submit button. Both the target URI as well as the method to use are included in that Web form so a client actually doesn't have to care about that fact. Through the affordance of the button element, a client also has the implicit knowledge that a button can be clicked and certain actions may be triggered as a consequence. The same concepts used in the Web should now be used between applications to interact with each other. Here, either HTML forms can be reused or certain, specialized media-types need to be developed (i.e. like hal-forms). Through content-type negotiation client and server can actually agree on a representation format both support and therefore avoid interoperability issues.
One common issue many "REST developer" seem to have is to think of REST endpoints returning certain data to be of certain types, i.e. the data of a company employee or the items of a certain hierarchies. Fielding claims that instead of introducing typed resources meaningful to a client, REST APIs should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and defining application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types.
A further thing to mentioned here, which I already striped a bit in my comment, is that URIs don't inherit a parent-child relationship by default. A URI as a whole, including any path, matrix and/or query parameters is just a link to a resource and can be considered as a key used for caches to return a response body previously stored for that key (=URI). Clients therefore shouldn't attempt to deduce semantic knowledge from URIs itself but just use the link relations returned for such URIs. This allows servers to replace URIs down the road while clients still can invoke them based on the name the URI was returned for.
As URIs themselves don't convey any semantic information, they can't really express a parent-child relationship on their own. We humans tend to interpret a URI such as /api/company/abc/employee/123 as expressing that employee with the number 123 is working for company abc, which might be true, but also does not have to be as explained before, URIs lack the semantic of expressing such things. It is only through the utilization of a bunch of such URIs that such a semantic tree can be created.
But In my case I have dependent entities that is parent and child. First I create parent entity using the POST. Now the child entity is created only after parent entity has been created.
If you take a closer look at the HTTP methods you might see that POST requests are processed according to the resource's own specific semantics, meaning that you literally can perform anything you have to here. This is defacto a swiss-army-knife in your toolset available and should be used if the other methods aren't fitting your use-case.
PUT i.e. is specified to replace the current targets representation with the one provided in the payload of the request. However, a server is allowed to validate whether the PUT representation is consistent with any constraints the server has for the target resource and may reject therefore requests to update a certain resource due to conflicts with certain constraints. PUT is further allowed to reconfigure a targets media-type to match a more suitable representation, apply a transformation onto the received payload to convert the payload to a matching one of the target resource or reject the payload in general.
Neither HTTP methods nor URIs can create such a semantic relationship between a parent and child resources. However, this is what link relations are there for! Links are edges between two entities that give a name to the context of the relation between those two entities. Such link relations should be standardized, follow common conventions or represent extension types as defined in RFC 5988 (Web linking) to promote their reusage. Unfortunately, however, IANA does not directly specify a parent and child link relation. up may be used to refer from a child to a parent, in a tree. Through an extension mechanism this is however relatively easy to obtain, i.e. http://api.acme.com/rel/parent and http://api.acme.com/rel/child or something similar.
The next bit to discuss on the quoted segment of the initial post would be happens-before semantics of the creation of the parent in contrast to the child resource. HTTP does not have any kind of transaction semantics nor guarantees of ordering of requests other than outlined in the pipelining section, which only applies to safe methods anyways. HTTP therefore does not give any promises to the processing of requests as they either might not reach the server at all or the response just got lost for whatever reason. Only if the client is receiving a 201 Created response including a Location header pointing to the created resource a client knows for sure that a resource got created and according to the specification only then a client is allowed to create a further child resource.
To a generic HTTP server both the creation request of the parent as well as the consecutive request of creating the child resource are two distinctive requests which it will attempt to fulfill independently. This is the stateless nature of HTTP. As mentioned before though, certain validation of resource's own constraints might be performed preventing the creation of children though.
Important points to note are that parent and child entity are linked by an id column only. So currently my url for creating child entity is /api/entities/parent-entity-id. Also there is no request body while creating the child entity as all the required info for creating is stored in parent entity.
REST doesn't care about your domain model actually. What you have here is a classical example of /persons resources, where three persons are identifiable via separate, distinctive URIs such as /persons/alice, /persons/bob and /persons/joe. We don't know anything about the actual data returned by any of these endpoints actually and by itself, as above mentioned, you can't deduce from the URI directly whose parent of whom (or that any of the URIs actually represents a person to start with). Through link-relation such a context structure can now be given, stating that Bob and Alice are parents of Joe and Joe is a child of both Bob and Alice.
Note how in the example above the actual content of the resources was not of importance to the client. We still don't know if either of the resources contain any information at all. All we know is that there are 3 resources available that are linked to each other in some way. So if the intent of your system is to just represent such relationships than go ahead. Use links between those resources to allow clients to lookup these relationships if interested. If a client is interested in the details of a resource it will send a request for a certain set of media-types to the server anyways. Discoverability and exploration are two common things you will want to guarantee in a REST ecosystem.
My question is that should this method be POST as we are creating the child entity or PUT as I am updating the children of the parent entity which already has been created?
AS POST is an all-purpose tool that has to be used if the other methods aren't fitting, using POST is for sure not wrong. If you take a closer look on the other methods you might see that they serve different purposes, i.e. PUT has the semantics of replacing the current content with the one given in the request payload. It therefore expresses a different use-case than you actually want IMO. As such you should stick to POST also for generating your children.
What you should do within your POST logic, as hopefully was clear enough throughout this answer, is to introduce meaningful link-relations that give the relations between the "entities" some context you can name. Such an operation can further have side effects which allows you to update the parent resource as well and introduce some further links that point from the parent back to the child.
This post is probably already way longer than it needs to be, though I want to make sure that you understand the intent behind REST and when to use it. Unless you really need a system that requires properties such as freedom for evolution, failure robustness and support for the operation of the application/system for decades to come, either exposing your own RPC service or maybe exposing your data model directly is probably easier to obtain.
Also there is no request body while creating the child entity as all the required info for creating is stored in parent entity.
So, this has nothing to do with resource state and therefore nothing to do with REST.
You're not PUTting a new state of a resource, so you should stay away from using PUT.
You are creating a new instance, so you should use POST method on endpoint for previously created parent instance.
Example:
POST /parent/<parent_id>/children/
BODY:
{"json with children data...."}
I am new to domain driven design and trying to learn and implement in my project. My project structure up till now similar to this.
Maintainance Folder Maintainance.Data(Class
Library) Maintainance.Domain(Class Library)
Maintainance.Domin.Tests(test project)
MovieBooking Folder MovieBooking.Data(Class
Library) MovieBooking.Domain(Class Library)
MovieBooking.Domain.Tests(test project)
SharedKernel Common things
Web Application MovieBooking MVC Web
Application(which have reference to MovieBooking Domain)
In Maintainance boundned context I am keeping all CRUD, GetAll type things for say Movie, Country, Category, Subcategory entities in Maintainance DBContext.
Now in MovieBooking data layer I will also need to use these entities (mostly to display name or dropdown fills in view, kind of subset needed - not all properties needed, only few like Id, name)
There are few ways I can access this entities in Movie booking Bounded Context
Via web services - Need to create web api for common entities like Movie,Country,Category,Subcategory and call web api in web project (to fill Dropdowns or get name from entities)
Via Reference Context (Seperate Dbcontext) - Need to configure Dbset and then map a database view (with only require fields) to Dbset
Example :
modelBuilder.Entity().ToTable(ViewName);
For (1) it can be long term implmentation solution for me
(2) I have to create view (with only few properties) for each require table and it will increase my number of views in my DB drastically as I have enterprise level application.
Is there any other way I can achieve this? Anything I am missing in DDD to look for ?
Option 2, while it will save you time, is actually a very bad idea from the DDD perspective as it allows for violations of the transactional boundary guarantees that each aggregate is meant to enforce\represent.
Option 1 seems a better option, although there are still quite a bit of wiggle room for interpretation based on your brief description of your proposed solution. If I understood correctly, it is generally recommended to follow the below:
Do not expose your aggregate state directly since this exposes internals and increases coupling. Simple create meaningful DTO's and use something like Automapper to map your Aggregates to DTO's easilly and with little effort before sending it over.
Have a duplicate of the DTO definition in your client. This will reduce coupling and allow for easier deployments.
I strongly recommend reading the DDD orange book although I have to say that I cannot recall specifically on which chapter this is discussed. You will also benefit a lot by reading about hexagonal architecture (and I would search for that term in the orange book to find more info about your question).
There is actually one alternative that I can think of: if you're publishing events from your BC's you can create a workflow to translate the domain events to "public" events and then in the other BC listen for the public events that you need to and store the data that you need somewhere inside there. The difficulty of this ranges from very easy to quite problematic depending on your infrastructure. Be aware that it is not a very good idea to re-use your domain events for transmitting data to other BC's since this closely couples the two BC's.
I hope this helps. Please do not hesitate to elaborate if I did not understood the question well enough.
I'm writing an API with spring boot, trying to keep it restful but the structure is quite nested. So say I have:
/api/examboard/{ebid}/qualification/{qid}/subject/{sid}/module/{mid}/
I have a controller for every noun that will take in all Id's, the problem with this is that I don't really need an ebid or a qid for modules, they only really need to be concerned with subjects most of the time. The mapping between them all is quite simple. An examboard will have many qualifications, a qualification will have many subjects etc....
Now the problem is say I go for a simpler API design where I only need the parent Id so the Subject controller will also have:
api/subject/{sid}/module
then I need to include multiple services in my controller based on the way JPA works. As I need to include SubjectEntity based calls and ModuleEntity based calls. However I want to maintain a one to one relationship between my controllers/services and services/repositories. This is why I opted for the longer url as I've mentioned above, but it does seem like overkill. Does anyone have any advice on how I should structure an API like this, most examples are quite small and don't really fit.
Without knowing more about your models and the relations between them, this answer will have to stay a bit diffuse.
First of all - "it depends". I know, but it really does. The way you should design an API depends heavily on your use cases that will define required access patterns. Do you often need all modules for a subject? Then introduce /subjects/{sid}/modules, if you need the details for a module of a subject in a qualification in an examboard - by all means have a /examboards/{ebid}/qualifications/{qid}/subjects/{sid}/modules/{mid}
As you say there are many relations between your entities. That is fine, but it does not mean that you need your API to capture each of these relations in a dedicated endpoint. You should distiguish between retrieving and modifying entities here. Find below examples for certain operations you might want to have (not knowing your models, this may not apply - let's consider this an illustration)
Retrieve qualifications for an examboard
GET /examboards/{ebid}/qualifications plain and simple
GET /qualifications?ebid={ebid} if you feel you might need sophisticated filtering later on
or create a new qualitication for an examboard
POST /examboards/{ebid}/qualifications with the details submitted in the body
POST /qualifications with the details submitted in the body and making the associated examboard ebid part of the submitted data
or update an existing qualification
PUT /qualifications/{qid} (if this operation is idempotent)
POST /qualifications/{qid} (if it should not be considered idempotent)
or delete qualifications
DELETE /qualifications/{qid} deletes entities, cascade-deletes associations
DELETE /examboards/{ebid}/qualifications clears all qualifications from an examboard, without actually deleting the qualification entities
There are certainly more ways to let an API do all these things, but this should demonstrate that you need to think of your use cases first and design your API around them.
Please note the pluralisation of collection resources in the previous examples. This comes down to personal preference, but I tends to follow the argumentation of Sam Ruby in RESTful Web Services (available as PDF) that collections should be first-class citizens in an API
Usually, there should not be a reason to have 1:1:1 relationships between controllers, services and repositories. Usually, this is not even possible. Now, I don't know the reason why you might want to do this, but following through with this will force you to put a lot of logic into your database queries and models. While this (depending on your setup and skills) may or may not be easily testable, it certainly shifts the required test types from unit (simpler, usually faster, more fine-grained) to integration tests (require more setup, more complex, usually slower), when instead of having the bulk of your business logic in your services you put them into many joins and subselects in your repositories.
I will only address your REST API structure question.
As you already pointed out
The problem with this is that I don't really need an ebid or a qid for modules, they only really need to be concerned with subjects most of the time
You need to think of your entities as resources if your entity can stand for itself give it its own top level resource. If instead your entity exists only as a part of another entity build a subresource below its parent. This should correspond with the association type aggregation and composition in your object model design.
Otherwise every entity that is part of a many relationship should also be accessible via a subresource on the other side of the relationship.
As I understood you you have a OneToMany relationship between examboard and qualification so we get:
api/examboards/{eid}/qualifications
api/qualifications/{qid}/examboard
Yo could also remove the examboard subresource and include it in the qualification response.
For ManyToMany realtionships you need two subresources:
api/foos/{fid}/bars
api/bars/{bid}/foos
And another resource to manipulate the relationship itself.
api/foosToBars/{fid}+{bid}
Or likewise.
REST has a uniform interface constraint which is the following in a very zipped opinion based format.
You have to use standards like HTTP, URI, MIME, etc...
You have to use hyperlinks.
You have to use RDF vocabs to annotate data and hyperlinks with semantics.
You do all of these to decouple the client from the implementation details of the service.
DDD with CQRS (or without it) is very similar as far as I understand.
By CQRS you define an interface to interact with the domain model. This interface consists of commands an queries classes.
By DDD you define domain events to decouple the domain model from the persistence details.
By DDD you have one ubiquitous language per bounded context which expresses the semantics.
You do all of these to completely decouple the domain model from the outside world.
Is it possible to map the REST uniform interface to the domain interface defined by commands and queries and domain events? (So the REST service code would be generated automatically.)
Is it possible to map the linked data semantics to the ubiquitous languages? (So you wouldn't need to define very similar terms, just find and reuse existing vocabs.)
Please add a very simple mapping example to your answer, why yes or why not!
I don't think this is possible. There is a term which I believe describes this problem, it is called ontology alignment.
In this case have have at least 3 ontologies:
the ubiquitous language (UL) of the domain model
the application specific vocab (ASO) of the REST service
the linked open data vocabs (LODO) which the application specific vocab uses
So we have at least 2 alignments:
the UL : ASO alignment
the ASO : LODO alignment
Our problem is related to the UL : ASO alignment, so let's talk about these ontologies.
The UL is object oriented, because we are talking about DDD and domain model. So most of the domain objects entities, value objects are real objects and not data structures. The non-object-oriented part of it are the DTOs like command+domainEvent, query+result and error on the interface of the domain model.
In contrast the ASO is strictly procedural, we manipulate the resources (data structures) using a set of standard methods (procedures) on them.
So from my aspect we are talking about 2 very different things and we got the following options:
make the ASO more object oriented -> RPC
make the UL less object oriented -> anaemic domain model
So from my point of view we can do the following things:
we can automatically map entities to resources and commands to operations by CRUD, for example the HydraBundle does this with active records (we can do just the same with DDD and without CQRS)
we can manually map commands to operations by a complex domain model
the operation POST transaction {...} can result a SendMoneyCommand{...}
the operation GET orders/123/total can result a OrderTotalQuery{...}
we cannot map entities to resources by a complex domain model, because we have to define new resources to describe a new service or a new entity method, for example
the operation POST transaction {...} can result account.sendMoney(anotherAccount, ...)
the operation GET orders/123/total can result in an SQL query on a read database without ever touching a single entity
I think it is not possible to do this kind of ontology alignment between DDD+CQRS and REST, but I am not an expert of this topic. What I think we can do is creating an application specific vocab with resource classes, properties and operations and map the operations to the commands/queries and the properties to the command/query properties.
You have posed some interesting questions here.
To start with I do not quite agree with
By DDD you define domain events to decouple the domain model from the
persistence details.
I think you might be confusing Event Sourcing ES with DDD, ES can be used with DDD but its very much optional in fact you should give it a lot of thought before choosing it as your persistence mechanism.
Now to the bulk of your question, of whether REST and DDD get along if yes how ?
My take on it, yes they do get along, however generally you do not want to expose your domain model via a REST interface, you want to build a abstraction over it and then expose that.
You can refer to this answer here, for a little more detail.
However i cannot recommend enough the Implementing Domain-Driven Design book, Chapter 14 Application deals with your concern to a fair degree.
I could not have explained it more thoroughly than the book and hence referring you there :)
I stumbled upon the following two articles First and Second in which the author states in summary that ORM Entities and Domain Entities shouldn't be mixed up.
I face exactly this problem at the moment as I code with EF 6.0 using the Code First approach. I use the POCO classes as entities in the EF as well as my domain/business objects. But I find myself frequently in the situation where I define a property as public or a navigation property as virtual only because the EF Framework forces me to do so.
I don't know what to take as the bottom line of the two articles? Should I really create for example a CustomerEF class for the entity framework and a CustomerD for my domain. Then create a repository which consumes CustomerD maps it to CustomerEF do some queries and than maps back the received CustomerEF to CustomerD. I thought EF is all about mapping my domain entities to the data.
So please give me some advice. Do I overlook an important thing the EF is able to provide me with? Or is this a problem which can not completely solved by the EF? In the latter case what is a good way to manage this problem?
I agree with the general idea of these posts. An ORM class model is part of a data access layer first and foremost (even if it consists of so-called POCOs). If any conflict of interests arises between persistence and business logic (or any other concern), decisions should always be made in favor of persistence.
However, as software developers we always have to balance between purism and pragmatism. Whether or not to use the persistence model as a domain model depends on a number of factors:
The size/coherence of the development team. When the whole team knows that properties can be public just because of ORM requirements, but should not be set all over the place, it may not be a big deal. If everybody knows (and obeys) that an ID property is not to be used in business logic, having IDs may not be a big deal. A scattered, unexperienced or undisciplined team may need more stringent segregation of code.
The overlap between business logic concerns and persistence concerns. Object oriented design thrives when a class model sticks to SOLID principles. But these principles are not necessarily at odds with persistence concerns. I mean that although the concerns are different, in the end their resultant requirements may be quite similar. For instance, both concerns may require valid object state and correct associations.
There can be use cases, however, in which objects temporarily need to be in a state that absolutely shouldn't be stored. This may be a reason to work with dedicated domain classes. Another reason may be that the entity model just can't fulfill the best segmentation of responsibilities. For instance, a business process "blacklisting customer" may require data that is scattered over so many entity objects that new domain classes must be designed that can encapsulate the data and the methods working on them. In other words: doing this by entities would violate the Tell Don't Ask principle.
The need for layering. For instance, if the data access layer targets different database vendors it may have to consist of interchangeable parts that are vendor-specific (e.g. to account for subtle differences in data types between Oracle and Sql Server or to exploit vendor-specific features). Using the persistence model as domain model would probably bleed vendor-specific implementations into the business logic. That would be really bad. There the data access layer should be precisely that, a layer.
(Very trivial) The amount of data. Creating objects takes time and resources. When "many" objects are involved in a business case it may just be too expensive to build both entity objects and domain objects.
And more, undoubtedly.
So I would always try to be a pragmatist. If entity classes do a decent job, go for it. If the mismatch is too large, create a business domain for appropriate parts of the business logic. I would not slavishly follow a (any) design pattern just because it is a good pattern. Contrary to what is said in the post, it requires a lot of maintenance to map an entity model onto a business model. When you find yourself creating myriads of business classes that are almost identical to entity classes it's time to rethink what you're doing.