POST request side-effects on RESTful API - rest

I'm building an API that enables clients to send emails to their subscribers. It may be that the subscriber is already registered with an unique id assigned to it. Therefore, a POST /emails/subscribers/:subcriberId endpoint exists that lets the client send an email to the subscriber identified by subscriberId.
Now, a new use case has arisen where a email may be sent to a unregistered subscriber. Instead, the email and the name of it will be specified in the request body.
I'm thinking to implement the following endpoint:
POST /emails
{
// email content and metadata
"receiverName": "John Smith",
"receiverEmail": "john#example.com"
}
It will be nice to use the receiver's data to create a new subscriber for future actions. But this would be a side effect of sending the email.
Is this an acceptable RESTful practice?
Notes:
I want to avoid the client having first to create the subscriber and the sending the email.
Subscribers are also uniquely identified by email.

Is this an acceptable RESTful practice?
Yes.
HTTP constraints the semantics of the request and the response. Implementation side effects are at the discretion of the server.

One way to get around your problem is to provide a POST /emails endpoint whose contract supports both use cases: send emails to subscribers and non-subscribers.
Regarding your API, I suggest you rethink your design as it violates some basic design principles. For instance:
collection resource names should be plural (i.e., /subscribers)
you should review the has-a relationships between your resources (i.e., a subscriber has an email, not the other way around).

If the POST here is associated to the standard CREATE method I think this is actually a side effect. Storing the email is not a side-effect but connecting to a SMTP server and send an email to a any recipient it is.

Related

Mail notification from denormalized view in CQRS

I want to develop a mail notification service to send order approval to customer. The order data is in the denormalized view (query side) and it should be filled to the mail template. Then, we send the email in html string format via mail notification service. But, the order status should be changed to "order approval email sent".
I also try to implement the CQRS, ES, and DDD concept in microservices architecture.
Is this procedure correct and still align with the concept?
Develop HTTP POST API in order command to send approval mail so the order status could be changed in command-side.
The command side generate the event "order approval mail processed"
The event processor process the event. It should get the order data from query-side / denormalized view.
The event processor generates the approval mail from the data and fill the data to the template.
The event processor call HTTP POST to the mail notification service with mail body (html format) in the payload.
The event processor call HTTP PUT to the order service (command-side) to change the order status to "order approval mail sent".
But, if this procedure is applied, the user can't get the response "mail sent" in real-time. How to trigger the client / front-end side that the mail is successfully sent? So, the client side don't have a need to refresh or retry many calls to the API.
Thanks.
I've written a post on this subject a while ago, you can find it here: How to Send Emails the Right Way in a CQRS System
The short version is that I would use a process manager. A process manager listens to events and can issue commands as a result of these events. Just make sure you have a mechanism to not re-send emails if you ever re-run your events.
Regarding the UI. I have another post dealing with this question. You can find it here: 4 Ways to Handle Eventual Consistency on the UI
Here is a short answer. How often do you think once the code is run to send the email, that the email fails to send? Assuming you have a reasonably robust system, I would hope the vast majority of the time it would work. So fake it. And only if there is a problem find some way to notify the user and or admin users. If you want to get fancy you can use things like Signalr or some pub-sub framework for sending messages to the UI.
Anyway - hope that helps.

Email Intermediary Between Sender and Receiver

I am using SES for emailing (currently only sending but I'm open to using it for receiving as well), EC2 server for web app and RDS.
Web application written in Java.
I would like to act as intermediary for users that email each other through my website by having all emails sent between users go through me.
The purpose is to conceal the emails of the two users who are emailing each other.
I thought of doing something like this:
1) The initial email is sent on the website, there it receives a unique ID which is stored in the database (containing the email addresses of the sender and receiver).
2) All subsequent emails between the two users are sent to the website's email address with the unique ID appended as a label (eg:bob+[uniqueId]#domain.com).
3) The email is accordingly routed back and forth between receiver and sender (I perform minor modifications to the email).
(Airbnb does something similar when users of its site message each other).
An extra caveat is that I would like attachments to be able to be included in the emails as well (and thus, they would need to be forwarded).
Is this the correct way to implement this functionality?
Should I do it differently?
If this is the correct approach, any references for how to get started? Specifically, I'm not sure how to use a lambda function (if that is what I would be using) to send an email, or to query my RDS.
Thank you
This sounds similar to private email systems I've seen on other sites. I think you have the correct idea. I would recommend using SES for both sending and receiving, and use a Lambda function to process the incoming emails.
You can have SES fire a Lambda function when you receive an email: http://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-lambda-example-functions.html
The other option for triggering processing of incoming emails would be SES->SNS->Java application webhook. Or you could queue them up via SES->SNS->SQS and have your Java application subscribe to the SQS queue.

Creating an email thread from IMAP?

I would like to create a "thread view" from emails that are on an IMAP server.
To achieve that, I fetch the list of emails in the INBOX and other folders but I need to know which email is answering which. Is there such a link between emails in IMAP?
For example on an IMAP server each email has a unique ID: if email B is an answer to email A, is the ID of A stored inside email B?
If your IMAP server supports the "thread" capability as described in RFC 5256, you can just ask the server to thread the messages for you.
Otherwise, you'll have to fetch the relevant information and do the threading on the client. The RFC describes two algorithms to do that. The simpler one, ORDEREDSUBJECT, just groups messages by subject and then sorts them by date. This gives a flat threading structure. The more complicated one, REFERENCES, looks at the In-Reply-To and References headers of each message, and considers messages with such headers to be children of the message with the given Message-Id.
The classic way is to retrieve the message-id and references fields. If two messages contain the same message-id in either message-id or references, then they are in the same thread.
Gmail has a new and IMO better way: each thread has a numeric ID which you can retrieve using x-gm-thrid. Google has published example code in various languages for using that (there should be links near that code).

How to send bulk emails with different subjects using Mandrill API?

How am I supposed to do to send bulk emails with dynamics subjects?
For example, If I need to send 200 emails at once, I don't want to call the Mandrill send() method 200 times because I suppose it's a very bad practice.
I'd want to call the send() method 1 time, putting my 200 recipients in the to attribute (this works well). However, in that case, how to set a different mail subject for each mail sent?
Thanks.
You can use merge tags within your subject to change the subject line for each user.
http://help.mandrill.com/entries/28499087-Can-I-use-merge-tags-in-my-subject-line-or-other-headers-
You can provide a default value for your merge tag and/or for each/some users personalised data.
Given the anatomy of an e-mail in Mandril is based upon subject and body (or template) to define a unique entity what you are asking to do isn't possible. A different subject or body constitutes a different e-mail and requires it's own .send().
If the same e-mail (same subject and body/template) was being sent to all receipts then a single .send() would work.

Transaction email(s) sender address

I am sending out transactional emails in my app and was reading up on best practices (for spam reasons obviously) and the following strikes me as odd.
I was expecting notification emails from Google, Facebook etc to have simple sender addresses like update#facebook.com/no-reply#plus.google.com etc.
But the actual addresses seem to be update+zj4o9ocoaz66#facebookmail.com, noreply-daa26fef#plus.google.com etc
Is there any reason, technical or otherwise, for not having a single/simple sender address when sending out transactional emails to all users?
While I can't speak to Facebook and Google specifically, the main reason for this is tracking and parsing of bounce notifications.
If you look at the headers you will see the 'Return-Path' is the same - no-reply+hash#example.org - this address is where mail servers should send automated bounces for NDR (non-delivery), such as 'inbox full' or 'nonexistent address', although some systems will use the 'From' as well, hence what you see.
The 'hash' part is often a structured piece of data that may help guide to particular clusters, determine the type of email, or identify recipients. You will often find ticketing systems use the same method to ensure your messages are directed to the same support agent if you reply.
While you could technically use the Message-ID header for this, that header tends to be a non-colliding 'random' hash rather than specifically structured data to assist routing without relying purely on lookup tables.