I'd recommend you make it clearer that the linking lines between nodes are clickable. Even better, rather than using a modal dialogue to display node contents, you could use a popover with an arrow pointing to it's owner. Clicking a link a the bottom of an item would simply move the popover, making the relationships between various items of content clearer.
On the topic of idempotence..we recently made our platform distributed across 4 datacenters using queues. None of us really knew what we were doing. Recognizing this very early on, we made all calls idempotent. Pretty sure that single decision is what made the entire system work.
I know they don't get too much love on HN, but it would be cool to see this done for a set of enterprise integration patterns.
The enterprise integration patterns links are interesting to me; thanks for point those out. I can definitely see how they could use a connection to reality. I can look at a random one and see what it is, but understanding why you'd use it is a mile above my head.
The link to Apache Camel is a bit more informative with actual examples with code snippets.
Idempotence (literally "same power) in a REST API means a given request produces the same result whether you execute it once or multiple times. Given the URL:
Whether you execute the DELETE method on that resource once or ten times, the resource is deleted. Therefore, it is idempotent.
Assume for the moment that DELETE on /resource/1 actually removes /resource/1 from the namespace, and doesn't do anything else (other than logging; logs don't count). If DELETE is idempotent in this case, then whether you call it one time or ten times, either way, /resource/1 is not there when you're finished, and nothing else has changed. The client might see an OK response to the first call and error responses to the others, but from the server's perspective, it's the same as if the call had only been made once. That's what makes it idempotent.
This seems like a rather hollow meaning of idempotency. HTTP is a communications protocol. Why bother specifying idempotency if it doesn't apply to the communications?
The client gets no benefit at all if the server doesn't faithfully serve idempotent responses, and in fact a great deal of the benefit of idempotency is lost. Specifically, the client cannot reasonably resume a dropped connection if the server changes its responses during a retry scenario (which RFC2616 says the client should do). Would it be idempotent if the first response to "PUT /foo" was 204 and the second response was 405?
void processRequest(httpcontext c)
// who cares?; this looks "idempotent" to everyone
c.status = rand();
Edit mfenniak suggests using HTTP 410 Gone instead, which makes more sense than 404 Not Found if you can configure your server to remember that a resource was deleted.
The spec regarding this:
"A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity."
204 is what I would return for most DELETEs because there is no status (entity) left after a normal delete.
As an API consumer, I would prefer a 404 not found - so that I may easily and accurately populate up the information that a resource I expected to be there, and to delete, wasn't there when I tried to delete it. Especially in complex applications where various clients may be running against the same data set across many distributed nodes, this can be demonstrative of many much harder-to-find problems when every action is "success."
I also would prefer 200 - with a description of the entity that was deleted, again, for verification and system maintenance needs.
Presumably, if you are logging status codes received by your client, you are also logging the requests that produce them; you should be able to determine if it is spuriously trying to delete the same resources from the request history. The only status code you need to make this determination is the 2xx received from the first successful request.
Consider that to catch two nodes deleting the same resource, you'd need to correlate the messages from all nodes. (Or, at least, know that there may be a problem with nodes trying to delete the same resource, and plan by recording every resource deleted in some other node.) Whereas, with a 404, you can determine that there is a problem in one message - and have the resource information to search through your history and find related events. Given that some of the systems I've worked in have had thousands of nodes - I'd rather not go through the log history from each node on every normal event to verify that it isn't actually abnormal. At a certain scale, relying on correlation and positive anomaly detection approaches such a level of difficulty as to be nearly impossible.
Generally, two nodes trying to delete the same resource isn't an anomaly. (The result of those attempts being something other than the resource being deleted exactly as if one attempt was made to deleted would be an anomaly, as it would the same node attmepting to delete the node more than once after having received confirmation that it had been deleted on an earlier effort.)
Because that is useful information. What benefit is there to hiding the information?
I think this is the crux of the debate is where do you draw the line?
If delete is considered idempotent despite changing the status code for repeated calls, then we must consider the status codes to be irrelevant to idempotency, which seems like completely wrong.
response.status = rand(); // is this really idempotent?
I find it farfetched that the spec authors would specify that an HTTP-compliant server should not do something completely unexpected in the face of a DELETE on a nonexistent resource. What's the alternative to "internal idempotency" here? To randomly restore the deleted item? To delete something else instead? Anything other than "note that the item is already gone and return" would be a bug. So why would anyone put this in the spec? They wouldn't, which is why the spec is clearly discussing idempotency with respect to the communications, and not with respect to the server's internal state (which again is not something the RFC mandates).
On the other hand, the RFC does specifically call out that clients should automatically retry idempotent operations in the event of a closed connection, which makes no sense if the communications will not be idempotent. The RFC also calls out that internal state may be changed in the face of an idempotent (and even a safe) operation, another indication that what's being specified is not internal server behavior/state (because if it's mutating state it's not internally idempotent).
> the client does something it shouldn't (for example, calling DELETE on a resource that no longer exists)
You're begging the question by assuming that a client should not call DELETE on a nonexistent resource. It's perfectly valid to interpret "DELETE" to mean "make sure nothing exists at this URL" (I believe the RFC does), in which case a delete of a nonexistent item is a successful call.
Ah, now I see the crux of the problem: you've mixed up safety and idempotency. It is perfectly all right for an idempotent action to change state, as long as performing the same action twice is functionally no different from performing it once.
This is different from safety (which some call nullipotency), where performing the action once or twice is the same as performing it zero times: i.e. nothing changes. The HTTP spec notes that it has no way of actually preventing servers from ensuring that safe actions change nothing, but it still warns server developers against doing so.
But the final proof that idempotency is not with respect to communications comes from the spec itself: RFC 2616, section 9.1.2, first sentence. The spec even explicitly states that error or expiration issues can cause different responses on subsequent requests, which is what makes it clear that idempotency is not with respect to communications.
"Not Found" is an error condition with respect to the server. That is a fact of the HTTP server specification: the client wanted to do something with a resource that the server couldn't find. It might be that this condition is precisely what the client wanted, but the server has no way to know that: it can only answer from its own perspective. It is up to the client to sort the matter out on its own, but fortunately, this is not hard. A client that expects for resources not to be found from time to time need only listed for these cases, and deal with them however it wants to. The server need never know.
>You're begging the question by assuming that a client should not call DELETE on a nonexistent resource. It's perfectly valid to interpret "DELETE" to mean "make sure nothing exists at this URL" (I believe the RFC does), in which case a delete of a nonexistent item is a successful call.
Actually, the RFC doesn't say that. The relevant section (9.7) states that DELETE is for actual requests to delete something. Nothing else. To "make sure nothing exists at a URL", the proper method is GET. You can also use HEAD if you're worried about a large entity-body taking up too much bandwidth. OPTIONS would work too, and it has the advantage of only touching the metadata, but not all servers support it.
That's not the miscommunication here. The reason I mentioned state mutation was only to clarify that the RFC does not dictate consistent internal server state. Even a "safe" call is only considered safe from the view of the caller. It also does not "warn developers" against changing state as a side effect of a "safe" call. It specifically states that this may be considered a feature, but that the user does not request any such side effects. Again, the concentration here is on the behavior of the communications, and not on the internal behavior of the server.
> But the final proof that idempotency is not with respect to communications comes from the spec itself: RFC 2616, section 9.1.2, first sentence. The spec even explicitly states that error or expiration issues can cause different responses on subsequent requests, which is what makes it clear that idempotency is not with respect to communications.
We're clearly reading this RFC differently. I see the error and expirations as being server-side. X expired? Sure, "GET X" will return a different result. Disk failed (aka error), certainly the response is going to change.
The RFC calls out changing the behavior in response to errors or expirations as an exception to idempotent behavior. I see this as confirmation that the server should behave consistency from the perspective of the caller except in cases where this is not possible.
> "Not Found" is an error condition with respect to the server. That is a fact of the HTTP server specification
I don't agree that "Not Found" is an error condition for delete. This is not in the spec. It's your interpretation of the spec. Nowhere in the RFC does it say "if a request comes in for X and X does not exist, a 400-level error should be returned". (If it did say that, PUT would be quite useless.)
> Actually, the RFC doesn't say that. The relevant section (9.7) states that DELETE is for actual requests to delete something. Nothing else. To "make sure nothing exists at a URL", the proper method is GET. You can also use HEAD if you're worried about a large entity-body taking up too much bandwidth. OPTIONS would work too, and it has the advantage of only touching the metadata, but not all servers support it.
You misunderstood what I was saying. "Make sure nothing exists" isn't an intention. It's a command. It's "Hey, server, make sure that when you return, nothing exists at location X." It's a delete, but a less "strict" version than yours, which is "Hey, go find out if something exists at X, remove it if so, and throw an error otherwise."
I don't think we're getting any closer to agreeing on this. I looked for a more definitive answer from one of the RFC authors, but couldn't find anything. It's just this same discussion playing out over and over with other people.
Making good abstractions for a complicated system is always harder than just a 1:1 API.
Ex. "Request = DELETE ID 1"
First request, ID 1 is deleted.
Second request, ID 1 has already been deleted.
Third request, ID 1 has already been deleted.
And, I don't even think it should be a requirement (depending on the role), if said boss hired you because you have the technical experience needed and trusts you, and is willing to learn, I wouldn't mind working for him.
My question was really, given this shared understanding. Why is this limited level of autonomy so common? How much longer can work that requires deep technical knowledge be directed and controlled by those who do not understand it.
In short, why are bosses not mentors. I don't mean in the general sense, I mean literally. My boss should be the person I respect, not who I answer to.
Don't get me wrong, all of those are generally good things, but if you can't draw up a diagram like that in 30 minutes for any design pattern, best practice or standard you follow, you should take that as a hint that you're doing something wrong.
I've variously heard people say both i-dem-PO-tent and i-DEM-po-tent. (In the latter, the "o" in "po" gets reduced to a schwa.)
Fixed point is another way to get at it, although it requires your listener to know what that is.
I mean if it were some consumer property, like say the size of a hard drive or such, then yeah makes some sense, for a term used in strictly in technical circles to describe a precise technical property, I don't understand what 'nicer' means.