Is there a better way to do this?
I think it should be. One idea that should be kept in mind is this: the point of a single interface is that clients and intermediaries do not need to know anything about the server implementation.
GET /people/bob/favoriteColors 200 OK []
If this is the starting point and we want to add a new color to the list
PUT /people/bob/favoriteColors [ "RED" : { "redChannel":255, "greenChannel":0, "blueChannel":0} ] 200 OK
No problem, we "created" your favorite color using PUT.
PUT /people/bob/favoriteColors [ "RED" : { "redChannel":239, "greenChannel":0, "blueChannel":0} , [ "BLUE" : { "redChannel":16, "greenChannel":16, "blueChannel":239} ] 200 OK
Again, no problem: we created BLUE and updated RED. Please note that we are intentionally isolated from the gymnastics that the server performed while accepting this update.
KeyValueStore.put(/people/bob/favoriteColors, [...]) KeyValueStore.put(/people/bob/favoriteColors/RED, {...}) KeyValueStore.put(/people/bob/favoriteColors/BLUE, {...}) KeyValueStore.put(/people/bob, {...,favoriteColors:{...}}) RDBMS.commit( [ favoriteColors.insert(BLUE : {}), favoriteColors.update(RED: {})
This is not to say that your api should not allow publishing directly on a new resource; it is also good.
PUT /people/bob/favoriteColors/OCTARINE { "redChannel":-inf, "greenChannel":Nan, "blueChannel":i} 201 CREATED
What you should keep in mind is that, from the perspective of your standard swamp, of the intermediate components, there is no implied relationship between /people/bob/favoriteColors
and /people/bob/favoriteColors/OCTARINE
. Changing one does not invalidate the cache entries for the other - the same interface that protects us from the details of the implementation of entries also protects us from side effects on other resources. When developing your API, you need to think about the implications of having multiple resources that can change the βsameβ state.
To some extent, you probably have this problem. Intermediaries will not know that
DELETE /people/bob
should also carve /people/bob/favoriteColors
In all the examples, at this point I used the full representations of the addressed resource. Allow all PUT - send a replacement view for the target resource. If you want to submit an idea of ββthe change, you need to think about PATCH or POST.
The combination of POST to create is false. I assume the link was accepted in response to the POST description in RFC 2616 . The language in [RFC 7231] views it as something more of all. POST is the only writing method supported in HTML, and the Internet is booming, so we have to deal with it somehow.
An additional way out is to send messages where all the interesting work is a side effect. This is similar to sending a message to the message queue. The target resource is the turn itself, so your requests and answers correspond to the conceptual model of adding a document to the collection; since the documents themselves are notions of work, not representations of results, they are separate from the domain model itself. This means that you can send a full view of the BeigifyColors
, which can be arbitrarily complex, for handlers tuned to this particular use case and watch for side effects in your views.
Command processing resources here, readable representations, are another expression of the CQRS pattern. As with PUT OCTARINE, intermediaries are not going to know which views to evict, but otherwise they handle the protocol perfectly.