Proper response code for RESTful API method [POST/PUT] when the entity from parameter doesn't exist (or the access is denied) - rest

I have a RESTful API method that creates/updates an entity (e.g POST /classes or PUT /classes/:id) with a few parameters. One of the parameters (e.g. teacher) is an ID of some other entity of a different kind.
My question is what is a correct response code for this method when the entity indicated by the parameter doesn't exist (or the user has no access to this entity).
My choice is (for both POST and PUT methods):
404 if the entity from parameter doesn't exist,
403 if we have no access to the entity from the parameter (but the information about existence of this entity is not a secret),
404 if we have no access to the entity from the parameter (in case the information about this entity should remain a secret).
I feel that this is very descriptive and clear (along with some error message). However, I'd like to consider potential alternatives or have a confirmation that my approach is not a bad design.

The 404 (Not Found) status code indicates that the origin server did
not find a current representation for the target
resource or is not willing to disclose that one exists.
-- RFC 7231
Emphasis mine. 404 is a non-sensical error in the use case you describe, because of course there is no current representation of the target resource - you're trying to create it. 400 would be a better status code, along with a response object explaining that the referenced object doesn't exist.

In fact, your case is not specified in RFC. Every status should refer to the entity (resource) requested by the URL. If non-existing resource is a parameter, then it is not a "target entity". The most adequate status is 400.

Related

Which HTTP method to use with REST API if we have parent-child entities and parent has already been created?

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...."}

Web services and partial entity updates

We are implementing CRUD interface to manage entities with SOAP messages. What are good practices to allow partial updating of the entity? Meaning the client could update just some attributes of the entity, without having to post the whole entity? Is there more general approach to this than distinct methods for each attribute update?
HTTP Patch can be used for partial updates, only sending the fields of the object you want to change. There's an interesting discussion about partial updates here.
I'd say it would be more important to make sure the partial update is idempotent, i.e. the same update fields in the request result in the same end state of the resource. So if you have internal logic that determines the state of a resource attribute based on the value of another resource attribute that is being updated that might be something to look into. e.g. if the resource as a whole has rules for when parts of it are updated but other parts are not specified (default values for some attributes?), that may cause different outcomes based on the current state of the resource.
If the resource as a whole is just a collection of unrelated attributes then partial updates make sense but if there are dependencies among some attributes and some get updated while others don't, then the end state of the resource has to be idempotent. e.g. does it make sense to update an address but not update the phone number? What happens to the phone number if it's a landline and the address gets updated? Is it set to null? and vice versa. So when doing partial updates it might be worth 'partitioning' the allowed partials based on the domain being updated.

Accessing modified attributes in katharsis when saving resource

When I implement a method annotated with #JsonApiSave in my katharsis repository I get a fully populated resource as a parameter, even though the PATCH request is only sending a single attribute. Is there a way I can find out which attributes have been updated?

Why is DELETE not supported on to-many-association resources in Spring Data REST?

I am using Spring Data REST. I am trying to unbind a collection association from an entity (item). i.e. - a property of the item is of List type. I want to remove all items from that List.
To do this, I am using the DELETE method:
curl -X DELETE …/categories/54ea0bcf27a2fb1b4641083a/fixedParentCategories
This gives me a 405 Method not allowed error code. But, it works for a single valued association (when it is not of List type). The documentation clearly lists DELETE as a supported method for associations. I'd like to know if there is a way around this. Also, I tried using PUT (Content-Type: text/uri-list) with an empty body, and it gives an error about missing request body. Other operations on this association are all working fine - I am able to add items to this collection, etc.
My entity looks like this:
#Document
public class Category {
#DBRef(lazy = true)
private List<Category> fixedParentCategories;
…
}
I just checked the code and you're right, we're actively rejecting DELETE requests for Maps and collections. The rationale is as follows:
An association that is of Map or collection must never be null in the domain model. Translating this into HTTP resources means that the resource will always be available and in the worst case return an empty representation (empty JSON array, or empty JSON object). Accepting a DELETE request would logically null the relationship in the domain model and thus lead to a state that contradicts the very first assumption.
We generally recommend to simply PUT an empty body with media type text/uri-list to the association resource to empty out the associations as that's semantically more correct. Consider it like the difference between truncating and dropping a database table.
If you think that should change and have good reasons that you can back your request with, feel free to open a ticket in our JIRA.

EJB module as a RESTful web service?

can I use an EJB module as a RESTful web service?
There is previous questions asked on the topic such as the one below, but they are from a year to 3 years ago. "Why can't i create a RESTful web service in ejb module?"
Has there been any upgrades since then.
Well, now it's possible (leveraging CDI).
See the JavaEE tutorial here.
Yes this can be done. Restful web services were initially described in the context of HTTP but I guess it is not limited to just that protocol. A good foundation knowledge of how the main HTTP operations are used would be good though.
So you will need the bean methods providing the service to follow fundamental rules.
The key things to note in the context of your implementation EJB module are:
Resources
(1) A resource is anything that has identity.
(2) Every resource has a URI.
(3) A URI is “opaque,” exposes no details of its implementation.
Resources are anything that can be used as "currency" for you service. If a client returns an object in a particular representation representing a dog from a particular method, they should be able to use that object to talk to other methods that may require something representing a dog. If that object representing a dog is to be used in multiple places then it has an identifier and a method for obtaining it. Method name + identifier = URI (unique resource identifier).
Protocol
(4)GET operations are “idempotent,” free of side effects.
(5) Any request that doesn’t have side effects should use GET.
(6) All interactions are stateless.
You may wish to implement bean methods in the form of getDog(Long dogID). Which is your URI for a dog of dogID identifier. All the methods with getXXXX() would have no side effects on the rest of the service. If only getXXX() were performed in on the service, the backend would not change one bit.
All interactions are stateless. So use nothing else but stateless beans.
Representations
(7) Data and metadata formats are documented.
(8) Data is available in multiple flavors.
(9) Representations include links to other resources.
So if that dog object which your client is using as "currency" has an owner referenced on it ( preferably this reference should be in the form of an identifier ie ownerID), the identifier can be used to obtain the full owner representation using getOwner(ownerID), its URI.
Style
(10) Document and advertise your service API.
(11) Use available standards and technology.
(12) Refine and extend architecture, standards and tools
Make sure your method names are self describing and common throughout. i.e. updateDog(Dog dog) , create(Dog dog) , deleteDog(Long dogID). So if the client wants to create an owner they will instantly know what the method name is by the name of the resource 'Owner' and the identifier which in a previous example was obtained by a reference in the Dog representation.
Sorry for the long answer.