I am designing a rest api and I have some doubts about exposing and consuming children from relation.
Assuming I have an entity A with a one to many relation to entity B (so A can have some Bs attached) and I design an endpoint to create entity A and DTO for entity A includes a list for entity B and user provides a valid one, should it be saved too?
Example:
Doing a post to some endpoint e.g. /api/v1/As
{
entityAfield1: someValue,
entityAfield2: someOtherValue
Bs: [
{
HERE a valid B payload
}
]
}
should I also save B and create a relation between A and B? What if B also have some children? Should it be saved too?
Or should I just save A and create an endpoint like
/api/v1/As/{Aid}/Bs/{Bid}
to create a relation?
And same question about getting data. Should get always retrieve all children? I couldn't find a clear answer to this on the web.
The issue might be solved by means of returning the IDs of Bs. This way, a user of service will decide whether or not to retrieve the actual data of related resources.
To interact with those an endpoint like this
/api/v1/Bs/{Bid}
can be used, as well as a more verbose one
/api/v1/As/{Aid}/Bs/{Bid}
however, the too nested endpoints, like
/api/v1/As/{Aid}/Bs/{Bid}/Cs/{Cid}/Ds/{Did}
should be avoided and most likely indicate a design flaw.
For a tree structure or many to many relations in general, an intermediate resource that represents a linkage should be exposed. There is a good example of a REST API implementation by Google, its "Children" section would be especially helpful for such case.
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...."}
Assume two tables in a relational database A & B, and a join table C. The join table is empty until relationships are explicitly added.
I'm exposing REST endpoints to add/remove these relationships (add/remove an entry in table C). They don't modify the entries in table A or B, but from a consumer's point of view the association of A to B is as important as the entities themselves. It will feel as though a resource is being modified. But what's actually happening is a row is being added/removed from table C.
Which verb(s) would be most appropriate for the add/remove endpoints? POST/DELETE? PUT/PUT? A case could even be made for PATCH (if I take the 'modified' route, i'm not replacing an entire resource, just a piece of it)
UPDATE: I'm seeing similar situations handled by creating a new resource (/api/friendships/create|delete). If this ends up being the answer so be it, but the relationship in my case is more like a playlist being added/removed from a library
Since the relationships are first-class citizens, the appropriate verbs would be POST and DELETE (or PUT and DELETE if relationships cannot be duplicated, i.e. if only one relationship may exist for each A-B pair). In a RESTful API, HTTP verbs typically more closely match the consumer's intentions than the server's implementation details (which are not the concern of the consumer).
Which verb(s) would be most appropriate for the add/remove endpoints?
How would you do it with a website?
The client would probably load some form -- it might have a list of A and a list of B, or it might assume a specific A and just provide a list of B. The user would make their selections from the choices in the form, and submit it.
Since that isn't a safe, you would probably specify that the method on the form is POST.
If the client knows what the representation of the relationship endpoint should look like, and knows what URI should be used for the relationship resource, then PUT might be appropriate -- at that point, you are effectively doing remote authoring.
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.
I'm using ASP.NET MVC3 with Entity Framework 4.
I am using the Unit Of Work + Generic Repository pattern.
I searched for similar question everywhere, I see that many people have my problem, but still can't find a good and practical solution.
We have a multi-tenant database.
Imagine a database with a similar structure:
customers
groups, associated to a customer
users, associated to one or many groups
And then, for each customer we have
resources, associated to one or many groups, and linked between each other with foreign keys, many-to-many relationships and so on
So, when a user logs in, he is associated to one or many groups, and he needs to have access to the parent and child resources associated to that groups.
Now the problem is:
I implemented a sort of pre-filtering with a .Where() clause into the unit of work, in the repositories, based on the id of the logged in user.
And this is working.
The pre-filtering I did on the repositories is working fine, but of course it works only if you access directly the repository of the sources of TYPE A or TYPE B or TYPE C and so on.
But a resource is linked to other resources with many-to-many tables and foreign keys.
So, it happens that sometimes a resource belongs to a group to which the user has access, but sometimes the resources linked to this resource belong to a group to which the user does not have access.
If I traverse the navigation properties of the "parent" resource, the user can access all the linked resources, even the one belonging to other groups.
So, if you are starting from a TYPE A resource, and traverse the navigation properties to reach the TYPE B and TYPE C resources, they are not filtered.
If you access the TYPE B and TYPE C repositories, they are filtered.
Now my filters, as I said before, are in the Unit Of Work class, but I tried to move them into a custom DBContext, applying the filters directly into the DBSet, but nothing changes:
It seems that EF is accessing directly the database to build the navigation properties, thus not using the other repositories or the other DBSet, avoiding the prefilter.
What can we do?
I see that NHibernate has Global Filters that could accomplish my task, so I'm evaluating a migration from EF to NH.
I see that many other people is asking for .Include() filters, thus disabling lazy loading.
Thank you.
I can provide some piece of code if needed, but I hope I explained my problem correctly.
Thank you i.a.
Best Regards,
Marco
I saw a solution with mapping to views and stored procedures, but I'm not sure how hard it was in development and maintanace. In short, it is possible to map EF model to views, where data will be filtered; in this solution each user have own database credentials.
I'm following these tutorials thoroughly and must say they're great tutorials!
http://www.techchorus.net/create-restful-applications-using-zend-framework
I'm just confused about the whole concept of Zend_Rest abstract methods. In the examples, you only see
index
POST
GET
PUT
DELETE
While these functions make sense, I'm trying to figure out if the whole architecture is only limited to those abstract methods. I'm thinking about a use case where a consumer wants to use the API to update specific fields in lets say the user table, or another case where the consumer wants to update activity table. The business logic of these two tables are covered in one RESTful api controller. I would tackle this problem by creating specific update/post method for each table, and have function parameters to define which fields are being updated. Would this kind of implementation conform with REST and if so how do you go beyond POST,GET, PUT, DELETE methods?
REST architecture does support hierarchical relationships for resources, and your resources are not bound with your database in any way. Your “User” resource might have a subresource “Credentials” that maps to username and password fields in your users table, so you could do a PUT request on “domain.com/users/{userId}/credentials”. You will implement this by creating a controller, say UserCredentials, and the update logic would be in the putAction.
You will have to modify the routing for this to work in Zend though. See How to set up Hierarchical Zend Rest Routes?