Code Monkey home page Code Monkey logo

Comments (7)

alexeymezenin avatar alexeymezenin commented on July 30, 2024 2

Hi. Thank you for the feedback.

I don't think it's best practice to pass a Laravel's Request object to the Service Layer.

$request->file('image') is not a Request object.

I don't like whereHas() example.

I always use Eloquent to keep the code maintainable. The tiny performance difference is not a problem for most of Laravel projects. Development and maintenance costs are more important.

If you have a couple of really slow queries that became a problem, you can always rewrite those into query builder queries or raw SQL queries, use cache etc.

I don't think mass assignment is a good practice, when your service is NOT TRIVIAL.

I always use the mass assignment feature. It's absolutely safe when you know how it works.

I think the document is leading people being tightly coupled to the framework.

Technically, that is correct but I still prefer to use the helpers because they make the code maintainable.

Overengineering is not good.

Don’t try to apply DDD for everything. Draw a context map and decide where you will make a push for DDD and where you will not (author of DDD)

Yes, the app will be tightly coupled with a couple of classes (not with the framework) but if you'll really want to transfer Laravel code to another PHP framework, this will be your smallest problem. By the way, it's super easy (cheap) to make all these helpers work in any PHP framework or in a vanilla PHP application.

Also, in the real world, a typical small business will keep using the existing app or rewrite the app using another programming language or framework from scratch rather than try to reuse old sloppy code in some new fancy PHP framework.

from laravel-best-practices.

skyrpex avatar skyrpex commented on July 30, 2024 1

If I'm not mistaken, what you're explaining is very similar to DDD. Here's is a recent blog post from Spatie people (I believe).

I have to say that I'm so happy I started working that way. Separating domain layers from the framework is so beneficial in terms of maintainability.

PD: Here's also a ValueObject library by Spatie.

from laravel-best-practices.

skyrpex avatar skyrpex commented on July 30, 2024 1

Of course, there's no silver bullet but this pattern worked for me for medium to large sized applications. Small applications can be coded whatever, though.

from laravel-best-practices.

appkr avatar appkr commented on July 30, 2024 1

@alexeymezenin Your answer is understandable, and totally I agree with you. I didn't mean to offend you (not a native speaker, so don't know write nicely), I just wanted to know how people think. Thanks.

from laravel-best-practices.

Konafets avatar Konafets commented on July 30, 2024 1

What you do is right ValueObject-wise, but Laravel is not ready for Value Objects. I used them the same way as you but it felt hacky. Every developer needs to know how to use them and since there is no object validation in Laravel you can assign any value to any attribute (existing or not in db) or create an empty object $user = new User (which is not correct if you User must have an address) and nobody (Laravel) will complain.

There is a blog post about this: https://www.ntaso.com/why-i-dont-use-value-objects-in-laravel-anymore/

from laravel-best-practices.

appkr avatar appkr commented on July 30, 2024

@skyrpex I have looked through the Spatie's value object. Thanks for the link.

I do like and really respect the Spatie people and their packages though, but this time, I will not buy the concept of the Value Object(VO) from them. I think they mix up the concept of VO between Data Transfer Object(DTO).

My idea is based on Martin Fowler's book "Patterns of Enterprise Application Architecture", and definitions of VO from the Red Book by Eric Evans.

If you are interested, the following is the VO example in a Laravel project based on which I understood the concept. You may say, a lot of boilerplate code. But the decision is yours. Since I work for a growing Logistics sevice which currently handles more than 500k requests in a minutes, this style of code gave me a peace of mind.

class CreateUsersTable
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('zip_code', 5);
        // ...
    });
}

/**
 * @property Address $address
 */
class User extends Model
{
    public function getAddressAttribute()
    {
        return new Address(
            $this->getAttributeValue('zip_code'),
            // ...
        );
    }

    public function setAddressAttribute(Address $address)
    {
        $this->attributes['zip_code'] = $address->getZipCode();
        // ...
    }

    public function scopeWithAddress(Builder $query, $search)
    {
        // Assume value $search was sanitized
        return $query->where('zip_code', 'like', "%{$search}%")
            // ->orWhere(...)
            ; 
    }
}

class Address
{
    private $zipCode;

    public function __construct(
        string $zipCode = null,
        // ...
    ) {
        $this->zipCode = $this->setZipCode($zipCode);
    }

    public function getZipCode()
    {
        return $this->zipCode;
    }

    private function setZipCode(string $zipCode = null)
    {
        if (is_numeric($zipCode) === false || mb_strlen($zipCode) !== 5) {
            throw new InvalidArgumentException();
        }
        $this->zipCode = $zipCode;
    }

    // ...

    public function isEqualTo(Address $other)
    {
        return $this->zipCode === $other->getZipCode()
            // && ...
            ;
    }
}

class SomeControllerOrCommandOrService
{
    public function doSomethingWith(User $user)
    {
        $destAddress = $user->address;
        // ...
    }
}

class UserCreator(CreateUserDto $dto)
{
    public function createUser()
    {
        $user = new User();
        $user->address = $dto->getAddress();
        // ...
        return $user;
    }
}

FYI, I got a lot of insights from these videos:

PS. Sorry! The code was written without help of an IDE, so there were several times of corrections. I think there still are errors though, but I hope the readers get the point.

from laravel-best-practices.

appkr avatar appkr commented on July 30, 2024

@Konafets Thanks a million for the feedback and the link. I've read the link as soon as it was posted, and read them again thanks to you. This thread made me think a lot in terms of software design as well as myself.

While reading the article and navigating supporting links, I encountered inexperienced day's myself, and became red-faced with shame.

Of the discussion I've read on this article, the following sentence teached me that I am going too far...

Eloquent is Active Record, not modelling tool for describing your domain

  • JarekTkaczyk

from laravel-best-practices.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.