The Postman, a simple Laravel pattern

By Diego | Dev Tutorials

Aug 11

This is a quick post about a common Laravel pattern that I’m using more and more these days. Just my way of organizing the mail sending features of my old Laravel apps.

So yeah, this is not about the movie “The Postman”, nor about The Marvelettes song, “Please Mr. Postman”. If you are disappointed, please don’t be. I will give you a little teaser at the end.

This article focuses on a pattern that I’ve been using from some time now on “older” Laravel apps. If you are working on projects with Laravel 5.2 or older versions, this might be useful… if you are not already doing something very similar.

Sending emails on Laravel 5.2-

Laravel provides really cool email sending features with its Mail API package, that wraps around the SwiftMailler library. Personally, I really don’t need anything else in terms of features, and I’m almost sure that neither the majority of the Laravel developers out there.

But when it’s time to actually send or queue your emails, where do you do that? In your Controllers? In your Models? You might have some sort of service class that handles some logic and sends emails as part of it? Or maybe on your event Listeners…

I’m almost sure you understand what I mean by now, but let me be clear. I’m referring to the place in your code are we putting this type of thing (take a look at the sendEmailReminder() method in this snippet from Laravel’s 5.2 own documentation):

<?php

namespace App\Http\Controllers;

use Mail;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Send an e-mail reminder to the user.
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     */
    public function sendEmailReminder(Request $request, $id)
    {
        $user = User::findOrFail($id);

        Mail::send('emails.reminder', ['user' => $user], function ($m) use ($user) {
            $m->from('hello@app.com', 'Your Application');
            $m->to($user->email, $user->name)->subject('Your Reminder!');
        });
    }
}

In my own apps the logic where the email is sent or queued usually lives in some service class. Usually the apps have several emails that are sent under different situations and I end up having these “sendEmail” methods distributed along several Service classes, that are actually responsible of very different business logic between them. This is ok, and I don’t think is a bad practice.

The Postman pattern for Laravel 5.2- apps

But not so long ago I started to move all these “sendEmail” methods to a central class, whose only responsibility was to compose and send the emails. It is a very simple class, that only does one thing: send the emails it’s asked for. And then, the Postman pattern emerged.

You might be asking why I might want to do this, when sending the email is just calling the send() or queue() method on the Mail facade? Well, actually is not “just” that in my case. The snippet example from Laravel is pretty simple, but in my own projects, the email sending involves a few more lines of code.

Again, let me be fully detailed:

<?php 

namespace App\Services\Mail;
use Illuminate\Support\Facades\Mail;

class Postman {

    /**
     * Send an e-mail reminder to the user.
     *
     * @param  User  $user
     */
    public function sendEmailNotificationToAdmins(Event $event)
    {
        // Get the template and subject
        $templates = config('my-app-module.emails.admin.event-notification');
        $subject = trans('my-app-module.subjects.admin.submission-updated');

        // Get all the admins:
        $admins = config('mail.admins');

        // Prepare data for the email:
        $data = compact('event');

        // Send the email
        foreach ($admins as $email => $name) {
            $data['name'] = $name;
            Mail::send('emails.reminder', $data, function ($m) use ($email, $name) {
                $m->from('hello@app.com', 'Your Application');
                $m->to($email, $name)->subject('Your Reminder!');
            });
        }
    }

}

As you can see, it’s not “just” calling send(). I get the templates for the emails from a configuration entry. The subjects come from translation files, and in this case, the email is sent to every administrator, who needs to be retrieved. This example can be even a little bit more complex if the recipients need to be users to retrieve following a certain logic, instead of just a bunch of array entries in a config file. Even though this is not that much overhead nor a ton of more lines, I really don’t like to have all that code mixed up all over my logic.

I prefer to have this instead:

$this->postman->sendEmailNotificationToAdmins($event);

Do we need a Postman from Laravel 5.3 onwards?

From it’s version 5.3 Laravel has a new concept for sending emails, that I really like. It’s a little bit different from this Postman pattern but a move in a similar direction, where you don’t end up having the Mail::send and other setting statements all around. You can read about in the Mail section of its documentation, but essentially boils to this: A Mailable base class that knows how to build the email itself. You extend this class for every message that you want to send. When you need to actually send the message, you create an instance of the class and send it using the new Mail facade. Clever and cleaner than before.

The new Mail facade and service is the one taking the role of the Postman. While I “built” my emails in each of the postman’s methods, the new Laravel pattern is even better. Instead of having a long postman with all sorts of methods, you simply create a class for each email. Organized, neat and brief. Love it. But I guess you already know it, if you read this story.

So… for old Laravel 5.2 projects or even older, the Postman pattern might be useful and centralize things a little bit, allowing your logic to not be filled with several email sending statements. But from Laravel 5.3 onwards, you might just use the built in Mail system. The subjects, views, attachments and the sender can all be handled inside the Mailable class itself. Only of the recipients logic is kinda weird it might justify to extract into a “Postman”, but other than that, I might choose to stick to the built in Laravel classes and methods.

Postman teasers for the olddies

For those who made it to the end, congrats. Here you have a brief distraction from your daily programming.

The Postman (1997) trailer, directed and starred by Kevin Costner:

And also The Marvellous Marvelettes “short” and “remade” version of Please Mr. Postman. You can listen to the original version here.

Follow

About the Author

I’m a software engineer and work as an independent software developer and consultant. Software development is my passion. I usually find some time to write in between my work and my other interests, sports and PC gaming!