Global Consistency of Deletion in GCS - google-cloud-storage

The following snippet from GCS docs:
Strong global consistency also extends to deletion (DELETE) operations on objects and update (PUT) operations that change existing object and bucket ACLs. If you delete an object and you receive a success response, an immediate attempt to download (GET) the object will result in a 404 Not Found status code. Likewise, if you change ACLs on an object or bucket and you receive a success response, the newly applied object or bucket ACLs are immediately available.
is perplexing, I thought that global consistency means I won't get a 404 Not Found error, right?

You will get a 404 error because the object no longer exists after the delete operation completes successfully. If it weren't for strong consistency, it would be possible to delete an object and then perform a GET on the object and get back the old, pre-deleted state of the object.

Related

what is good practice for api call to return get/delete request?

I have api call to get children of a person and api to delete child of person:
GET http://localhost:9000/api/person/1/children
DELETE http://localhost:9000/api/person/1/child/2
currently when someone call get children by person id I return 200 if the call succeed and a list of the children id's if there are children and if no children so empty list. and 500 if anything else.
and when you want to delete a person child by their ids i return 200 if the call succeed (also case there is no person and children ids combination in my db table), and 500 if anything else.
my question is, should I give more descriptive error incase there is no relation between those..? the db call only return 1/0 in case of deletion so to do something like this it means i need to perform another db call to check it, or tell the user if its 0 so nothing happened (and this incase db call did not find a record)...
thanks
A 500 error is just a generic server error response, I would be inclined to use a 404 when trying to call a get or delete as this indicates that the resource was not found, this can be either because there was an issue with what was sent to the API (such as junk data) or because the resource actually doesn't exist.
Should you want to do an extra db call is entirely up to you, often premature optimizations don't provide much in the way of benefits. However if you were to be facing 1000 calls a second it would probably be better to just let it fail and handle that gracefully than to check before.
10.4.5 404 Not Found
The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Is it good to use the Http DELETE verb to define a REST API that delete a single specific object?

I am implementing some REST APIs and I have a doubt about what HTTP verb should I use to implement an API that remove a single record from my DB
I thought that I should use the DELETE method but reading here:
http://www.restapitutorial.com/lessons/httpmethods.html
Reading the DELETE verb defintion I can read:
405 (Method Not Allowed), unless you want to delete the whole
collection—not often desirable.
So it seems to me that I have to use DELETE when I delete the whole collection and not a single element. Or it fit also the use case in which I am deleting a specific object (passing the ID of this object into my URL)?
Looks like you have misunderstood the content of the link you posted.
The DELETE HTTP method can be used to remove a single resource or a collection of resources.
However, in most of situations, you don't want to allow the client to remove the entire collection, so you return a 405 status code indicating that the DELETE method is not allowed in the collection URL.
In more practical terms, consider that you have a collection of customers mapped to /customers.
A GET request to such URL will return a representation of this collection. A DELETE request to such URL will delete all customers from your application. It's very likely you don't want that, so you return 405 to indicate that deleting all customers at once is not allowed. In the other hand, you want to allow the client to delete a single customer by performing a DELETE request to a URL that locates a single customer, such as /customers/{id}.
If the request succeeds, consider one of the following status codes, as defined in the RFC 7231:
If a DELETE method is successfully applied, the origin server SHOULD
send a 202 (Accepted) status code if the action will likely succeed
but has not yet been enacted, a 204 (No Content) status code if the
action has been enacted and no further information is to be supplied,
or a 200 (OK) status code if the action has been enacted and the
response message includes a representation describing the status.

How and when to create a new JwtConsumerBuilder when keys in the HttpsJwks cache have gone stale

This question is in regards to the jose4j JWT library. I am planning to create a single JwtConsumerBuilder instance for processing all incoming requests. I read here on stackoverflow and in release notes that JwtConsumerBuilder is multi-thread safe. I also plan to use the setVerificationKey method to validate the signature. When the key expires, I assume I will get an exception. Which type of exception will be returned: InvalidJwtSignatureException or InvalidKeyException?
When such an exception occurs, my plan is to update my global instance of the JwtConsumerBuilder with a new instance after retrieving the updated key through the class HttpsJwksVerificationKeyResolver. Is this a sound approach or does the resolver take care of this for me.

What should DELETE /collection do if some items can't be deleted?

I have a collection of items and some of them may or may not be deleted, depending on some preconditions. If a user wants to delete a resource (DELETE /collection/1) and there are external dependencies on that resource, the server will return an error. But what should happen if the user wants to delete the entire collection (DELETE /collection)?
Should all the resources which can be deleted be deleted and the server return a 2xx, or should the server leave everything intact and return a 4xx? Which would be the expected behavior?
As a REST API consumer, I'd expect the operation to be atomic and maybe get back a 409 Conflict with details if one of the deletes fails. Plus the DELETE method is theoretically idempotent as #jbarrueta pointed out.
Now if undeletable resources is a normal event in your use case and happens frequently, you may want to stray from the norm a little bit, delete all that can be deleted and return something like a 206 Partial Content (don't know if that's legal for DELETE though) with details about undeleted resources.
However, if you need to manage error cases finely, you might be better off sending separate DELETE commands.
I think the proper result is 204 no content by success and 409 conflict by failure because of the dependencies (as the others pointed out). I support atomicity as well.
I think you are thinking about REST as SOAP/RPC, which it is clearly not. Your REST service MUST fulfill the uniform interface constraint, which includes the HATEOAS interface constraint, so you MUST send hyperlinks to the client.
If we are talking about a simple link, like DELETE /collection, then you must send the link to the client, only if the resource state transition it represents, is available from the current resource state. So if you cannot delete the collection because of the dependencies, then you don't send a link about this transition, because it is not possible.
If it is a templated link, then you have to attach the "removable" property to the items, and set the checkboxes to disabled if it is false.
This way conflict happens only when the client got the link from a representation of a previous (stale) resource state, and in that case you must update the client state by querying the server again with GET.
Another possible solution (ofc. in combination with the previous ones) to show the link and automatically remove dependencies.
I guess you can use PATCH for bulk updates, which includes bulk removal, so that can be another solution as well.
I'd say it depends on your domain (although I'd rather use DELETE /collection/all instead of DELETE/collection/),
When you have the situation where you use delete all but some items can't be deleted, it depends on your domain where if you are doing the delete all to free up resources where if not your business process suffers, then it's better to delete what can be deleted and put other into a retry queue makes sense. in that case response should be OK.
Also situations could arise where there could be two operations
Clean Up - only delete unused
Delete All - delete all
In either situation I'd rather use specific method rather than using DELETE on the root URL,
for Clean Up - DELETE /collection/unused
for Delete ALL - DELETE /collection/all

REST API error code when updating a resource that was deleted in a previous operation

Let's say we have a PUT(update) operation on a resource that was already deleted from the server
What should be the API response code ?
4xx - client issue, don't try to send the same query again
or
5xx - server issue, the resource couldn't be found on server
or
neither of these above ?
First of all, be careful with mapping CRUD operations to HTTP methods. PUT is not an update method. PUT is a request to replace the entity stored under the URI with the entity being supplied. This can be used to update, if the full representation is given (no partial updates with PUT, please) but can also be used to create, when you know the full representation and the resource URI.
So, the answer really depends on the server-side semantics. In principle, if the resource was already deleted and a GET to the same URI would return a 404, then a PUT should recreate it, with the representation supplied.
If that's not desired, and you don't want a client to be able to recreate a resource that was deleted before, then I'd say your deleted resource should return a 410 Gone response code when the client tries a GET on the URI, making it clear that the resource existed at some point but it's not coming back, and an attempt to replace it with a new representation should fail with a 409 Conflict, detailing how the current state doesn't allow that.