Skip to content

Back end

energyyear edited this page Jun 30, 2020 · 6 revisions

1 Content

  1. Content
  2. Introduction
  3. Architectural Design
  4. Domain
  5. Rules and guidelines
  6. Bibliography

2 Introduction

The WPL application is built upon Laravel, an MVC framework for PHP which is currently running on LTS version 6.2. Functionality of the backend of the application is approachable through a browser which will call a corresponding controller. The application tries to adhere to Laravel practices, there are several exceptions which will be discussed in this document. Future architectural decisions should be made on the rules and guidelines set out in this document to keep development uniform. It is advised to follow the book Implementing Doman Driven Design by Vaugh Vernon for further development or refactoring.

3 Architectural Design

The Laravel is a framework built primarily for making model-view-controller applications. MVC separates an application into three logical components which each are built to handle specific development aspects. Requests enter through a controller which in turn will consult the model layer to carry out business logic, the result of the executed business logic will be returned to the controller who will call the corresponding view which will be shown to the user.

3.1 Component/package diagram

To keep development consistent and uniform it is recommended to follow the rules set out by the package-diagram as truthfully as possible. The components follow a layered architecture which mostly means calls can only be made to a referenced layer. Layers are not allowed to be skipped since this will make the architectural style unnecessary. The diagram below shows how the code in each component should be organized into packages and the dependencies between them.

Component Diagram
The views component is not a real component but reflects the front-end.

3.1.1 Common

The Common components should only contain utility code (DTO’s, helper classes, etc.) used across the entire application. It mostly houses packages which the Laravel framework generates and does not depend on any of the packages it points to, which is mandatory. To know how to manage the existing packages in this component consult the Laravel documentation.

3.1.2 UI

Although the name implies otherwise the UI component handles incoming requests. The name is chosen because technically a controller is an endpoint for a user interface thus does not belong to the business layer. In practice the component can be found in a map named Http, this is the current Laravel naming convention for this layer. Note that controllers should only handle requests and nothing else which should prevent redundancy and promote reusability. To know how to manage the existing packages in this component consult the Laravel documentation.

3.1.3 Business

The Business component contains the applications domain model its corresponding services and factories. Services should always be built on top of a domain class or aggregate of domain classes which should be enforced with dependency injection in the constructor. To build aggregate objects it is advised to make use of the factory pattern which can be stored in factories which for now can be found in Services/Factories but should be stored in Model/Factories since Factories create objects. A factory should only build an aggregate object and nothing else. If implementations do else, they should be.

3.1.4 Persistency

The persistency component which currently is housed in a map called Repositories exclusively handles communication with the database. Communication is done through a pattern called the repository pattern in which aggregate classes are represented by repositories. The best place to call a repository is in the business component in a service.

4 Domain

Currently the domain is anemic and lacks cohesion, this is partly because attributes lack type hinting though PHP fully supports an object-oriented domain model.

4.1 Refactoring

The domain is currently spread across multiple folders, for example folders named Analysis and Tips house parts of the domain.
If a developer does not have any knowledge of the existence of these folders, chances are redundant domain classes will start appearing. To secure navigability and prevent redundancy, it is important to keep the Domain model in one folder called Model from which the domain model can be separated into subfolders. It is advised to refactor the domain model and its services with the help of the book Implementing Domain Driven Design by Vaugh Vernon. The book discusses multiple ways to create (aggregate) objects which are semantically rich and contain functionality. Some of the services are covered by Unit Tests which can be found in a map called tests. To give a head start I advise the following roadmap for refactoring the domain:

  • Relocating: place all classes according to the Component/package diagram even if they do not exist.
  • Refactor controllers: move business logic to business layer.
  • Refactor services and factories: according to E2E and unit testing.
  • Refactor domain: in-line with Domain Driven Design.
  • Refactor repositories: according to aggregates created by DDD.

When refactoring the Domain please be cautious to adhere Laravel conventions and rules set out in this document. It is advised to update the overarching chapter once changes have been made.

5 Rules and guidelines

Besides the rules set out in other chapters in this document there are several ubiquitous rules and guidelines which should be adhered in all PHP class files. This chapter should be changed when Laravel doc’s or other architectural decisions make the rules invalid.

5.1 Dependency injection

Even though Facades and Contracts provide an easy way to use dependencies in classes, dependencies should be gathered through dependency injection via the constructor. This is done through type-hinting the type in the constructor which Laravel will automatically resolve using reflection. Dependency injection makes testing easier and allows us to see quickly which dependencies are used in a class.

5.2 Adhere PSR-12

All PHP files should follow the PSR-12 coding style guide for uniformly readable code, if it isn’t implemented in existing files they should be refactored.

5.3 Single Action Controllers

Currently most of the application uses controllers like the Laravel documentation describes them. However, new controllers should be single action controllers. If a single resource requires multiple controller files, they should be in grouped in a directory. Documentation on how to use them can be found here.

5.4 Translations

Translations should be added and modified manually by editing the lang files here. Another approach is to use the Laravel Translation Manager package, available in dev environment at localhost/translations. Instructions on how to use it can be found at its github page. React/JS translations are stored here. These are compiled to the public/messages.js file with php artisan lang:js. Don't forget to compile whenever you add new translations that are used in React/JS. Laravel has three ways to use translations:

  • Lang::get('namespace.key')
  • trans('namespace.key')
  • __('namespace.key') or __('string to translate') with the latter using .JSON files first. Only use the __('') function as it will check both JSON and normal translations files, removing the need to decide which helper to use.

6 Bibliography