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?
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.
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.
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.
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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With