Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The effects of adding a Service Layer to a Laravel application

I have been developing with Zend Framework for a number of years and am now learning Laravel.

In my previous applications I usually have a Service Layer that is called by controllers. The Service Layer sits across the top of a Mapper and a Domain Model and is responsible for some application logic, raising events, some input filtering, etc.

Is there any reason why I should not implement a Service Layer in Laravel? In the examples that I have seen so far, controllers work directly with domain objects (or more accurately, active records).

If my Laravel controllers called my Service Layer, would I lose any of the advantages of Laravel? (As far as I can see I can still use Route/Model binding).

As a secondary question - what would be the best way to implement my Service Layer? As a collection of Service Providers, perhaps?

like image 638
DatsunBing Avatar asked Jan 29 '17 22:01

DatsunBing


People also ask

What is the use of Service Layer?

A service layer is an additional layer in an ASP.NET MVC application that mediates communication between a controller and repository layer. The service layer contains business logic. In particular, it contains validation logic.

What is Service Layer in Laravel?

The Service Layer is a design pattern that will help you to abstract your logic when you need to use different front-end on your application, for your domain logic.

What is the use of services in Laravel?

The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods.

What is Services folder in Laravel?

The Services directory contains various "helper" services your application needs to function. For example, the Registrar service included with Laravel is responsible for validating and creating new users of your application.


1 Answers

I also switched to Laravel coming from Zend and missed my Services. To sooth myself I have implemented a Service namespace which sits in namespace App\Services. In there I do all my Model or data handeling I don't want to see in my controller etc.

An example of my controller layout:

<?php
namespace App\Http\Controllers;

use App\Services\Contact as ContactService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Lang;

class IndexController extends Controller
{

    /**
     * Create a new controller instance.
     *
     * @param Request $request
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->_request  = $request;
    }

    /**
     * Standard contact page
     * 
     * @return contact page
     */
    public function contact(ContactService $contactService)
    {
        $errors  = null;
        $success = false;
        if ($this->_request->isMethod('post')) {
            $validator            = $contactService->validator($this->_request->all());
            if ($validator->fails()) {
                $errors = $validator->errors();
            } else {
                $contactService->create($validator->getData());
                $success = true;
            }
        }
        return view('pages/contact', ['errors' => $errors, 'success' => $success]);
    }
}

The services return validators, handle cruds, basically do everything that I don't want to see in my Controller just like I had it in my Zend projects.

Example of Service:

<?php
namespace App\Services;

use Validator;
use Mail;
use App\Models\Contact as ContactModel;

class Contact
{

    /**
     * Get a validator for a contact.
     *
     * @param  array $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    public function validator(array $data)
    {
        return Validator::make($data, [
                'email'     => 'required|email|max:255',
                'phone'     => 'max:255',
                'firstName' => 'required|max:255',
                'lastName'  => 'required|max:255',
                'message'   => 'required'
        ]);
    }

    /**
     * Create a new contact instance after a valid form.
     *
     * @param  array $data
     * @return ContactModel
     */
    public function create(array $data)
    {
        //Handle or map any data differently if needed, just for illustration
        $data = [
            'email'     => $data['email'],
            'firstName' => $data['firstName'],
            'lastName'  => $data['lastName'],
            'language'  => $data['language'],
            'phone'     => $data['phone'],
            'message'   => $data['message']
        ];
        
        // Send an email
        Mail::send('emails.contact', ['data' => $data], function ($m) use ($data) {
            $m->from(config('mail.from.address'), config('mail.from.name'));
            $m->to(env('MAIL_TO', '[email protected]'), env('MAIL_TO'))->subject('Contact form entry from: ' . $data['firstName']);
        });
        
        return ContactModel::create($data);
    }
}
like image 184
Kevin Peters Avatar answered Nov 15 '22 10:11

Kevin Peters