i am writing a restful webapp using Spring 3. Part of the app is a form which when submitted triggers the sending of an email with various application log files attached. I'm not sure whether i should handle this form submission as a 'POST' or a 'PUT'.
My issue is that structurally the process would seem to be idempotent (and therefore a candidate for a PUT) - the same request submitted n times with the same data will always send an email with the same textual content, with the same files from the same file system locations attached.
However the content of the attached files is likely to be different for each execution of the request.
Is the content of these files beyond the scope of what i should be interested in when deciding on PUT or POST? Am i missing the point here completely?
Any thoughts would be much appreciated
Many thanks in advance!
I would definitely go for POST as each time you post your data a new email will be sent/created. PUT is mostly used to edit existing entities.
Can you do a GET on the url that you did the PUT on to return the same resource? If not then use POST.
It matters less what the server does after the request. What is important is that the behaviour is consistent to the client. If a client PUTs a resource, it expects to be able to GET it afterwards. If you make the client do POST then the client has no expectations, unless you return a 201 in which case it expects the Location header to contain the newly created resource.
The issue of sending multiple emails if you PUT twice is debatable. As long as the number of emails sent is not exposed to the client then you are not violating the behaviour of the uniform interface. However, someone else in the system may get confused by the fact that they are receiving multiple interfaces.
Related
Hi i am for the time being building a REST Api and i am wondering about an idea i have for secure data posting.
I have data that i have to delegate to two different endpoints in the same Post and i am wondering if there is any way to "test-post" to the endpoints before posting for real solving the problematic scenarion in which one of the systems that i'm sending to would be down for a moment.
That is if one of the systems would be down i could return a failed request message instead.
For extra explanation of my thought:
User posts data objet to my api via endpoint.
I process data and later try to send processed data to two different systems via their endpoints in same process/method.
IF systems ok then data is sent, and i return a OK.
Else One of systems not ok i roll back (that is not sending processed data to either one of them), and return for example 500 Internal server error.
It is critical that when i send the data it has to be sent to both systems in same process, or none of them in same process if one system is down.
Hope i got you guys to understand what i am after.
I am developing a small REST API. As I got into analyzing all the possible failure scenarios, which I have to handle to create a reliable and stable system, I went into thinking about how to make my APIs atomic.
If we take a simple case of creating a contact through the POST API.
The server gets the POST request for the new contact.
Creates the contact in the DB.
Creates a response to send back to the client.
The server crashes before sending the response.
The client gets a timeout error (or connection refused?)
The client is bound to think that the contact creation has failed, though, in fact, the contact was in the DB.
Is this a rare case we can ignore? How do big companies deal with such an issue?
To handle this, you should make your write APIs idempotent i.e. If the same operation is executed multiple times, the result should be same as the operation was done only once.
To achieve this in your current example, you need to be able to identify a contact uniquely based on some parameter, say emailAddress. So, if the createContact is called again with the same emailAddress, check in the DB if a contact already exists with the emailAddress. If so, return the existing contact. Else, create a new contact with the emailAddress and return it.
Hope this helps.
If the request times out, the client should not make any assumption about whether it failed or succeeded.
If it is just a user making a request from a web form, then the timeout should just be exposed to the user, and they can hit the back button and check whether the operation succeeded or not, and if not they submit the request again. (This is fine as long as you always keep a consistent state. If your operation has multiple steps and fails mid way, you need to roll back.)
However if reliable messaging is important to your application you will have to use a library or build your own reliable messaging layer. This could work by having the client assign a unique ID to every request, and having another request that lets you check the result of that request ID later. Then you can do automated retries but only where necessary.
We have a pair of REST applications that are trying to achieve a light version of transactions by using an acknowledgment URL that indicates that it is time for both sides to "commit" the modification. Here are the steps - these are not done instantly - there might be pauses for end user approval between the steps.
Application A approves and stages the change notifies Application B
that it is ready to make the change
Application B stages the change and notifies Application A that it
is ready and provides an acknowledgement URL that Application A will
"hit" when it does the commit.
Application A "hits" the acknowledgement URL, upon receipt,
Application B commits the change and returns a 200. If Application
A gets a 200 they commit the change otherwise everyone rolls back.
The question is what is the right operation to do with respect to the acknowledgement URL. There are two "reasonable" choices - each with disadvantages:
Use a GET request - The flaw is that data is being modified and that
should not be allowed with a GET.
Use a PUT request - This makes more sense as data is changed and it
is only suposed to happen once. But PUT requests require a
Content-Length header and since there is no data to send, many HTTP
client libraries refuse to set "Content-Length: 0". So they produce
a "broken" PUT and you often (rightly) receive a 411 when you send a
PUT with no content-item. The solution is to send a single character
body - it makes the PUT valid but feels a bit yucky.
This is a narrow question asking if we should design the protocol with a GET or PUT with a single character body.
Just to be clear, not all HTTP clients refuse to send Content-Length: 0 header but the Java HttpURLConnection will only send the header if you actually send data on a PUT. And not all HTTP servers throw 411 when they get a PUT with no Content-Length header - but Rails (and others) rightly enforce the rule. We need this protocol to work across all languages, HTTP servers, and HTTP clients so an answer of "rewrite it all in X" is not helpful.
This is a REST philosophy question, not a "which language is better" question.
I am building an GWT application with lot's of forms. I am using gwt-platform with its dispatch module.
The next step in my mind is to prevent double-submits ON SERVER SIDE. The problem is that I don't know how to do it exactly...
I thought of something like this:
When application loads the server gives some generated token to the client
The server stores the token inside HTTPSession
When the client submits a form it will send the token from (1.) along with the form
The server checks if the sent token == token inside HTTPSession
In the answer to the client it will send a new token
Is it safe to store the token inside HTTPSession? Or should I simply create a HashMap on the server that maps from SESSION_ID to generated token?
Or maybe there is already an implementation of that in GWT or gwt-platform or somewhere else?
Thanks
The question you'll have to ask yourself first is: What is the kind of problem scenario you want to avoid?
The user accidentally (or out of frustration, ...) clicking a button twice.
A resource that is available only once (like a reservation for a certain seat in an airplane) being consumed twice.
Don't just say "I want to avoid both". Even if you do, you'll have to deal with the two problems separately.
Problem 1
This is better solved on the client side (e.g. by disabling the button once it is clicked).
It can also be solved on the server side (by checking sequence numbers or tokens or maybe the hash code of the contents, ...), but I don't really see the point. If the user really wants to submit twice (e.g. by manipulating the JavaScript such that the button doesn't get disabled), then just let them: Problem 1 is not about security.
Problem 2
This must (except in very specific situations) be solved on the server side. It's chiefly about security. But when you think about it, this problem can't be solved by double-submit prevention! Why not?
Let's look at our example: A seat in an airplane must be reserved only once. This can be violated in multiple ways:
By double-submit.
By the same user submitting at the same time e.g. from different browser windows.
By mutliple users trying to reserve at the same time.
The clean way to solve the problem is to check for availability of the seat atomically with reserving the seat. It doesn't really matter, if a violation was caused by double-submit (accidental double-submits are covered by problem 1).
... and Problem 3
If you have implemented some auto-resubmit mechanism, then you might also encounter a third kind of problem:
Let's say the user wants to add an item to his shopping cart. The client submits, and doesn't receive a response from the server before time-out. So it sends again automatically. The server however receives both messages, and tries to process them both - so it adds the item twice to the shopping cart.
The best solution to avoid this in my opinion is generally not to use actions like "add one item to the cart", but "set the target count of items to 1". Again, you could also work with sequence numbers etc.
So, 'Litmus', a web app for testing emails and webpages across browsers and email clients, has a proprietary method that they claim is able to track not just opens, clicks, browsers, etc (standard with an embedded image and pass-through link tracking.)
What's unique is they claim that they are able to track what actions the end user took, how long the end user read it for, and if they deleted or forwarded the email. They claim they do this without JavaScript, and purely using embedded images. They claim that the method works across most major email clients.
What could they be doing to track this? Obviously, if they're doing it with third party applications that they don't control, whatever they are doing should be replicable.
I'm thinking that they realized that when an email client forwards or deletes an email, it 'opens' the email in a different way then normal, creating a unique user string on the server log of some kind? I'm grasping at strings, though.
http://litmusapp.com/email-analytics
Details here http://litmusapp.com/help/analytics/how-it-works
EDIT: It also looks like they track Prints. Maybe they do this by tracking calls to the 'print' css?
It's all done with good ol' image bugs. Breaking down how they find out...
Which client was used: Check the user-agent
Whether an email was forwarded: Done by attaching image bugs to divs that are loaded only when the message is forwarded.
Whether an email was printed: bug attached to print stylesheet
How long it takes to read an email: A connection that's kept open, as pointed out by Forrest (this is also how Facebook tracks(ed?) whether or not you are online on chat).
Whether an email was deleted: Check If a message was read for a short period of time or not opened. In fact, they group "glanced" and "deleted" together.
Of course none of this will work if email clients disable images in emails.
EDIT: Here's another question on this:
The OP actually has their tracking code, and this answer here explains how it works.
One way I can think of doing that is having an embedded image that loads from a script on a server. The script would not return anything or maybe send data really slowly to keep the connection open. Once the email is deleted the connection would be closed. This way they could know how long the email was open. Maybe they just assume if it's open for less than 10 seconds it was deleted?
Another way is tracking the referrer - this would give a lot of data on what a webmail client is doing, but I doubt it would be useful with a desktop client.
They know when the email is opened (it's when the image is called from their http server).
They also know what the user do and when since they can easily replace all links with their own tracking URLs redirecting to the original link.
There is nothing exceptional here. They are just a bit more advanced than their compatitors. There is no magic.
I have only one doubt: how they track delete. Technically, there is no way to know what happened to the message after it was read.
I suspect that a "deleted" mail is a mail that is never opened.