(How) Can a UPDATE changes the TYPE of a RESOURCE?


#1

Imagine the following situation. 2 types of resources. The first type is ‘requested_x’ the second type is ‘accepted_x’.
To create an instance of ‘accepted_x’ there must be an instance of ‘requested_x’ before which ‘updates / changes’ to an ‘accepted_x’ .

How to model this?
Idea A - "Use one type with a status attribute."
That would be a possible solution, but for some “external” reasons, I don’t want to use it in this case.

Idea B - “Let the client deal with it”:
Use a CREATE request to create ‘accepted_x’ and then a DELETE request to delete ‘reqested_x’.
Disadvantage: There is no ‘transaction / transactional-behaviour’ meaning the the client can ‘forget’ to call the DELETE etc.

Idea C - “Use PATCH”:
Use a PATCH request to update the ‘requested_x’ to a ‘accepted_x’.
Where in my case the type and maybe also the id of the resource will change.
Advantages:

  • The requirement that the resource of type ‘requested_x’ exists is easy to prove.
  • The UPDATE / DELETE of the old resource happens on the server (transactional-behavior).
    Is this allowed by JSON API?
    How would the response look like?
    How would the client be informed about the deletion?

Idea D - “CREATE with DELETE”:
Use a CREATE request to create the ‘accepted_x’ instance. The reference to the ‘requested_x’ instance comes within the CREATE requested and is used to a) check the existence and b) delete it after the creation.
How would the response look like?
How would the client be informed about the deletion?

Are ‘Version’ attributes and meta data informations (‘links’…) the way to go?


#2

I’m sure there is some integration abstraction which is causing this awkward model, however I also think you could be thinking about this problem in a different way.

The main issue seems to be that you have a transformation, and a CRUD mentality which requires X must be deleted if Y is to exist. I assume through your descriptions you intend to have the resources available at different URIs, and therefore are seeking the correct way to go from request->accepted resources.

The ‘D’ idea you list is the appropriate choice, but the reasons why are the answers are to the questions you asked in the ‘C’ idea.

Resources, and the messages you send to them are not objects but a representation of the data available on the server. A resource in that sense, is just a projection of the state of something presented to you in that way behind the veil of the remote server. If you send a message to your ‘accepted_x’ with an appropriate relationship to the ‘requested_x’ resource, there is nothing wrong with one side effect of that message being the ‘deletion’ of the ‘requested_x’ resource. The HTTP methods are not CRUD operations, but signals of your intent with respect to the resources you are interacting with. The key here is understanding the server is not constrained by user interaction to manage it’s resources as required. You don’t need and should not require the consumer to perform your service logic for you, if you do then your service is poorly designed.

This does however bring up the problem of your client knowing that the side effect has taken place, with a variety of ways to address it. The ‘CRUDiest’ way would be to create a transaction resource (option ‘C’), which would ‘point’ to each resource and the clients would know the state once the links were dereferenced. A better option, would be do absolutely nothing, and allow the client to try to use the resource and handle the 404 if at any point an interaction was made. However, if the client is expected to maintain a list of ‘requested_x’ which can be transformed this wouldn’t help much.

Assuming there is a requirement to maintain or have the list previously mentioned, the best option is to use hypermedia to control the flow of information to the client. In this I see two options. The first is a link to the root of the collection of ‘requested_x’, or a link named ‘deleted/transformed/…etc’ which is semantically applicable to your domain which references the canonical URL of the ‘requested_x’. The first would account for keeping the cache updated for changes to the collection which did not originate from this client, but would be a larger message payload. The latter would update the particular client cache doing nothing to update the caches in intermediary clients nor update the cache for other changes, but would provide the quickest interaction without a network trip.

To your final question, no version attributes are not the way to go, but as described hypermedia links are, just not ‘meta’ data links speaking in terms of JSON-API.

Good luck!


#3

@michaelhibay thank you for your reply and your ideas. I like them, especially that “resources are not objects, but are a representation of them”.

I already started with the implementation of option ‘D’ and it worked quite good so far. The idea of offering hypermedia links to the clients for updating their states looks promising for me.

Thank you once more for your reply full of ideas.