11

I am trying to use nodemailer in expressjs app. Should I keep creating of transport object out of route handler or creating transport object inside route handler is just fine?

var express = require('express')
  , app = express()
  , nodemailer = require('nodemailer');

  smtpTrans = nodemailer.createTransport('SMTP', {
      service: 'Gmail',
      auth: {
          user: "me@gmail.com",
          pass: "application-specific-password" 
      }
  });
  app.post('/register', function(req, res){
    smtpTrans.sendMail(mailOptions);
  });

or

var express = require('express')
  , app = express()
  , nodemailer = require('nodemailer');

  app.post('/register', function(req, res){
    smtpTrans = nodemailer.createTransport('SMTP', {
      service: 'Gmail',
      auth: {
          user: "me@gmail.com",
          pass: "application-specific-password" 
      }
    });
    smtpTrans.sendMail(mailOptions);
  });
Yalamber
  • 7,360
  • 15
  • 63
  • 89
  • The documentation states that *"The same transport object can and should be reused several times."* (see [here](https://github.com/andris9/Nodemailer#setting-up-a-transport-method)), so I guess the correct way is your first example. – Paul Mougel Jan 14 '14 at 10:44
  • That will keep the SMTP connection on always right? – Yalamber Jan 14 '14 at 11:24
  • Indeed. Which is what you'd want if you send a lot of messages in order to reduce the connection time overhead. – Paul Mougel Jan 14 '14 at 11:33
  • 1
    What happens if my SMTP server goes down at some point or when initiating app? – Yalamber Jan 14 '14 at 11:36

1 Answers1

10

You have to think about your use case to make a choice.

The SMTP transport in nodemailer creates a connection pool that you explicitly have to close. This is good because the connection always stays open: you only suffer the connection delays (including TLS negotiation, etc.) when the app starts up.

Your first solution is then good if you send a lot of messages: by keeping a connection open you'll minimize the delay and resource utilization by using the connection pool.

On the other hand, your second solution is good if you send few messages: there's no need to maintain a connection if you send one email per hour. Be careful, as your current code is a bit wrong: you need to explicitly close the connection pool. If you don't, the connection pool will stay open even if you loose the reference to the object.

smtpTrans = nodemailer.createTransport('SMTP', { … });
smtpTrans.sendMail(mailOptions, function (err, responseStatus) {
  smtpTrans.close(); // Don't forget to close the connection pool!
});

From the looks of this issue, it seems that all errors are reported in the err parameter of the smtpTrans.sendMail callback.

Edit: This answer was written for Nodemailer 0.7. 1.0 is now out and has a few breaking changes, including on how it handles transports and connections. See this blog post for more information.

Paul Mougel
  • 16,728
  • 6
  • 57
  • 64
  • Will it be smtpTransport.close(); or smtpTrans.close();? – Yalamber Jan 14 '14 at 18:07
  • 2
    Nodemailers connection pool is "lazy", connections are kept alive only if there is some mail to send. This also means that if you do not close the transport explicitly then open SMTP connections will stay around until the server closes these for inactivity - eventually reaching the same closed state that you would have had with transport.close(). Most probably you do not want unused connections around though. – Andris Jan 14 '14 at 18:56
  • 2
    So it is better to create transport outside of the request handler? Also will it reconnect incase my SMTP server is down at any point? – Yalamber Jan 15 '14 at 10:56
  • 2
    Yes, if there is no available connections when sending mail, a new one is created automatically by the pool. You only get errors if the server is down at the exact moment you try to send mail, otherwise it doesn't matter if the server is down or not. – Andris Jan 16 '14 at 08:56
  • FYI, on ubuntu, I set up my own smtp mail server and using nginx, I send a mail almost every 3-5 day, I got 504 (Gateway Time-out) next time mail sent, I think nodemailer coudn't keep smtp connection alive in my case. – Imskull Aug 25 '14 at 01:19