I'm getting familiarized with Cloud SQL API (v1beta1). I'm trying to update authorizedNetworks (sql.instances.update) and I'm using API explorer. I think my my request body is alright except for 'settingsVersion'. According to the docs it should be:
The version of instance settings. This is a required field for update
method to make sure concurrent updates are handled properly. During
update, use the most recent settingsVersion value for this instance
and do not try to update this value.
Source: https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/update
I have not found anything useful related to settingsVersion. When I try with different srings, instead of receiving 200 and the response, I get 400 and:
"message": "Invalid value for: Expected a signed long, got '' (class
java.lang.String)"
If a insert random number, I get 412 (Precondition failed) and:
"message": "Condition does not match."
Where do I obtain versionSettings and what is a signed long string?
You should do a GET operation on your instance and fetch the current settings, those settings will contain the current version number, you should use that value.
This is done to avoid unintentional settings overwrites.
For example, if two people get the current instance status which has version 1, and they both try to change something different (for example, one wants to change the tier and the other wants to change the pricingPlan) by doing an Update operation, the second one to send the request would undo the change of the first one if the operation was permitted. However, since the version number is increased every time an update operation is performed, once the first person updates the instance, the second person's request will fail because the version number does not match anymore.
Related
We have a Restful API. In the response of the PUT API, we update the updated timestamp column in the database with the current time and return its value as part "updated" timestamp field in the json response.
My question is if none of the fields in the entity are updated in the PUT call, should the updated timestamp be changed or not?
To elaborate, when performing the same PUT call multiple times, without change in the entity data, should the updated timestamp change?
Are there any best practices?
The HTTP spec specifies that a PUT request should receive a complete representation of the resource and either create it if it doesn't exist (and respond with status 201 Created and empty body), or completely replace it if it does exist (and respond with 200 OK or 204 No Content status and empty body). That's (almost) all. Most APIs of course ignore the "no body should be returned" part.
The "updated" timestamp should not be treated as part of the resource, but rather as metadata about the resource, and updating it should be considered a side-effect of the request, which is out of scope of the spec and so you can treat it however you think is appropriate for your use case.
In my opinion it should NOT be updated because these timestamps are usually used for caching purposes, and since the resource has not been changed there's no reason to invalidate any cache (also keep in mind that PUT requests are not cacheable at all according to the spec). Another use case for the timestamp would be to show final users when the resource last changed, and in that case it would make no sense to update the timestamp if nothing has changed, it would just confuse users.
As an example, Ruby on Rails does not update the updated_at timestamp if no attributes of the model changed.
I would say that update date should reflect what actually happened.
If you actually updated the record (e.g. performed real database UPDATE call), then change the timestamp.
If you didn't actually do anything (e.g. just compared values and did nothing), then do NOT change update date. It would save you plenty of time if requests you're considered identical were actually not.
Also, as mentioned above, returning updated timestamps is not fully semantically correct, better use headers (Last-Modified for instance).
I have an application that takes user's input personal details (name, dob, etc.) and looks for a match in the database. I am not creating a record, nor editing one.
Now normally I'd use GET, but GET doesn't allow me a body, and all the data that needs to be checked has to be sent up. I run a database query against all the user's inputs to find a match. If the database returns a match then one is found, otherwise it returns an empty array and no match is found.
So can you recommend the correct RESTful method (HTTP) that I might use for this?
Thanks
As the semantics of the payload of a POST operation are defined by the service itself, it should be used in any case where the other operations do not fit. POST is therefore not only used to create new resources but also to trigger certain calculations and stuff like that.
The general question however is, why do you need such a method? If you fear overwriting any changes done by an other client to the resource between you fetching the state of a resource and requesting an update, i.e., you should consider using conditional requests as defined in RFC 7232 where either an ETag hash is calculated for the current state or the Last-Modified value is taken and added to response header. A client could then send the request including the payload to check first including a If-Match or If-Unmodified-Since header requesting the server to apply an update only if the precondition holds. If it fails the server would tell you that with a 412 Precondition Failed error response.
Need some guidance on best practices for building a RESTful API in node.js
Let's say I have a person record like so:
{
id: 1,
name: 'Jon',
age: 25,
recordVersion: 1
}
If I need to increment the recordVersion every time a value gets changed, would I still use a HTTP PUT to update this record? I've researched on how PUT should be idempotent and should contain the newly-updated representation of the original resource, so I am no sure of what to do.
I could increment the recordVersion property on the first PUT call and send an error on the second PUT call with the same versionNumber of 1 (because it would have incremented to 2 at that point), but does this follow RESTful API standards?
Representation != State
The resources sent over the wire are a representation of the state, not the actual state.
It's perfectly fine to remove the recordVersion and to update it behind the scenes - however if you do that, it would be best to remove it from the representation returned by a GET to that resource as well. To understand why: idempotency is all about what would happen if you applied the operation multiple times in a row (it isn't guaranteed if other operations happen in between...), and about observable side effects.
PUT the data without the version
the data is updated
version code incremented
if you did a GET you would get the data you had PUT (with no version)
PUT the same data again without the version
the data is updated
version code incremented
if you did a GET you would get the same data you had PUT (with no version)
Idempotent, because the resource representation has not changed as a result of calling PUT twice, even though the internal entity state has changed - no observable side effects.
See http://restcookbook.com/HTTP%20Methods/idempotency/ for a bit more detail.
Using version codes to detect conflicts
As you note, you could use inspect the version and throw an error if it has changed - and in fact this is very RESTful, and in my opinion the best way to approach PUT as it helps avoid (often inexplicable) concurrency errors. If you detect this case, it would be appropriate to return a 409 Conflict http status code.
How this would work is:
PUT the data with the version (v1)
the data is updated
version code incremented
if you did a GET you would get the data you had PUT with the new version (v2) (this is a side effect, but it's ok to have a side effect from the first time you do an operation).
PUT the same data again with version (v1)
conflict is detected because v1 != v2
409 Conflict returned
if you did a GET you would get the same as the result of the first operation - the data you originally PUT with the version v2
This is idempotent, because there have been no observable side effects as a result of calling the operation twice.
The client should, in response to a 409, do another GET to get the latest version code, and possibly offer to the user the opportunity to merge their changes with whatever else has changed in the meantime.
Often people confuse idempotency with thinking that the response to the operation must be the same as a result of multiple calls, but that is not the case - it is about there being no observable side effects as a result of multiple sequential calls.
I want to implement a "get changed values" capability in my API. For example, say I have the following REST API call:
GET /ws/school/7/student
This gets all the students in school #7. Unfortunately, this may be a lot. So, I want to modify the API to return only the student records that have been modified since a certain time. (The use case is that a nightly process runs from another system to pull all the students from my system to theirs.)
I see http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/ recommends using the if-modified-since header and returning a representation as follows:
Search all the students updated since the time requested in the if-modified-since header
If there are any, return those students with a 200 OK
If there are no students returned from that query, return a 304 Not Modified
I understand what he wants to do, but this seems the wrong way to go about it. The definition of the If-Modified-Since header (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24) says:
The If-Modified-Since request-header field is used with a method to make it conditional: if the requested variant has not been modified since the time specified in this field, an entity will not be returned from the server; instead, a 304 (not modified) response will be returned without any message-body.
This seems wrong to me. We would not be returning the representation or a 304 as indicated by the RFC, but some hybrid. It seems like client side code (or worse, a web cache between server and client) might misinterpret the meaning and replace the local cached value, when it should really just be updating it.
So, two questions:
Is this a correct use of the header?
If not (and I suspect not), what is the best practice? Query string parameter?
This is not the correct use of the header. The If-Modified-Since header is one which an HTTP client (browser or code) may optionally supply to the server when requesting a resource. If supplied the meaning is "I want resource X, but only if it's changed since time T." Its purpose is to allow client-side caching of resources.
The semantics of your proposed usage are "I want updates for collection X that happened since time T." It's a request for a subset of X. It does not seem like your motivation is to enable caching. Your client-side cached representation seemingly contains all of X, even though the typical request will only return you a small set of changes to X; that is, the response is not what you are directly caching, so the caching needs to happen in custom user logic client-side.
A query string parameter is a much more appropriate solution. Below {seq} would be something like a sequence number or timestamp.
GET /ws/schools/7/students/updates?since={seq}
Server-side I imagine you have a sequence of updates since the beginning of your system and a request of the above form would grab the first N updates that had a sequence value greater than {seq}. In this way, if a client ever got very far behind and needed to catch up, the results would be paged.
I have a scenario in which I have REST API which manages a Resource which we will call Group. A Group contains members and the group resource is dynamic - whenever you retrieve it, you get the latest data (so a query must run server side to update the number of members in a group - in other words, the result of the request is to modify the data, since the results of running the query are stored).
Given a *group_id* it should return a minimal amount of information like
{
group_id: "5t7yu8i9io0op",
group_name: "That's my name",
size: 34
}
So a GET to this resource causes the resource to change, since a subsequent GET could return a new value for 'size'. This tells me it is not idempotent and so you should use POST to retrieve this resource. Am I correct in this conclusion?
If I am correct, do you think it is advisable to also provide a GET method that only returns the currently stored data for the group (eg. so the size could be out of date, even the name too). I suppose in this case I should return a last-modified date as one of the fields so that the user knows how up-to-date the resource is and can then elect to use the POST method...but then I am left wondering why would anyone do that, so why not ONLY provide the POST method and forget about GET?
Confused I am!
Thanks in advance.
[EDIT]
#Satish posted a link in his/her answer to the HTTP specs. In section 9.1.1. it ends with this sentence:
Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.
So in my scenario, the requester does not really care about the side-effect that the value for 'size' is recomputed as a direct result of making the request. They want the group information and it just so happens that to provide accurate, up-to-date group data, the size query must be run in order to update that value. Whilst making the request causes data to change implies this should be a POST, the user did not request that side-effect and so therefore a GET request would be acceptable and more intuitive, would it not? And therefore still be restful according to this sentence.
[2nd EDIT]
#Satish asks a very important question in the comments. So for others who read this I'll explain further about this problem:
Normally you would not run the group query to update its size from a REST request. As members are added or removed from a group, you would update the computed size of that group, store it and then a simple GET request would always return the correct size. However, our situation is more complicated in that a group is only stored as a query definition in ElasticSearch (kind of like a view in an RDBMS). Members do not get added/removed to and from groups. They get added to a much larger set of data (a collection in MongoDB). There are hundreds, potentially thousands, of different 'group definitions' so it is not practical to recompute size for every group when the collection changes. We cannot know when an item is added/removed to/from the collection which groups might change size - you only know by running the group definition who is in that group and what the size is. I hope that clears things up. :)
You should use GET. Even if dynamic resource is changing, you did not request for that change through your request and you are not accountable for that change. Ref: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
In your case when you do a GET you retrieve some information about the Group. You don't modify the group structure. Ok, the group can be changed by an external entity so your next GET may bring you another data. Am I right? Who modifies the structure of the group and when?
So you should use GETbecause the resource it will be modified from somewhere else and not by your call that tries to do a read operation.
EDIT
After your edited the question I just want to add that I agree about the side effects.
It matters if you sent data or a change command explicitly to the server or you just read something and you don't have to pay attention for what the server side is doing to gave you the response. More intuitively:
GET - Requests data from a specified resource
POST - Submits data to be processed to a specified resource
It is the combination of GET and POST. So you should use POST.
Refer : http://adarshdchaurasia.wordpress.com/2013/09/26/http-get-vs-post/
You should not use GET because if you use GET method then search engines may cache the responses. It may cause unintentional data update at your server side, which you do not want. GET method is meant to return content without updating anything on server. POST is meant to updated the things at server and return result against that operation.