Share E-Book
Scan to open this page

Scan with your phone to open this page

Author: Martin Joo

Rating No ratings yet

"Domain-Driven Design with Laravel" is the complete guide to mastering DDD the Laravel way. The book covers topics like: - Simplifying ugly controllers with the help of Actions - Leaning out your models with Custom Query Builders - Using View Models to query data for a specific page - Writing very high-level code with Custom Collections - Getting rid of random arrays like $data using Value Objects and DTOs - Removing annoying status strings like draft or approved with States and Transitions - Structuring your code using Domains and Applications - Applying CQRS in the most simple yet effective form - …And much more All of the above by building a complex, real-world application. No “hello world” or “smells like a Youtube tutorial” examples. We will implement an e-mail marketing application such as ConvertKit or MailChimp, to be more precise.

AI Reading Assistant

Whole-book reading guide from stratified index samples; jump to passages in the text

AI guide
【One-Line Pitch】 A practical, project-driven guide to applying Domain-Driven Design (DDD) patterns inside Laravel, showing you how to build a real-world email marketing platform (like ConvertKit or MailChimp) while keeping your code clean, testable, and maintainable. Ideal for Laravel developers who want to move beyond tutorials and learn how to structure complex applications with Actions, Value Objects, View Models, and more. 【Book Arc】 - **Opening (~0%–3%)**: Introduces the core promise—mastering DDD the "Laravel way"—and contrasts it with the author's past experience of writing overly complex, factory-heavy code. Sets the stage for a pragmatic, framework-native approach to DDD rather than a purist one. - **Early (~3%–13%)**: Lays the foundational building blocks: Value Objects (wrapping scalar data with formatting logic), custom Eloquent casts, and the debate between repositories and custom query builders. The author argues that query builders are the more Laravel-idiomatic equivalent of repositories. - **Early (~13%–19%)**: Introduces Actions (invokable classes for single-use operations), View Models (for preparing page-specific data), and States/Transitions (replacing status strings with class-based state logic). These patterns are shown with concrete code examples. - **Early (~19%–29%)**: Shifts to the demo application—an email marketing platform. Describes the core features (subscribers, tags, broadcasts, sequences, forms, tracking) and begins designing the domain model, including the `sent_mails` polymorphic table for tracking sent emails. - **Middle (~29%–48%)**: Covers code organization by Domains (e.g., `Domain\Subscriber`, `Domain\Shared`) and Applications. Explains how to handle the User model, BaseModel, factories, and global scopes (like `UserScope` for tenant-like filtering). Introduces DTOs via the `laravel-data` package, which unifies Request, Resource, and DTO into one class. - **Middle (~48%–end)**: Demonstrates practical implementation details: building subscriber lists with pagination, using View Models with Inertia.js, creating APIs from the same codebase, and handling CSV imports with tag creation. The book concludes by showing how all patterns work together in a complete, real-world flow. 【Key Takeaways】 - **Value Objects turn scattered scalar data into cohesive, typed objects** (Early): Instead of passing raw floats or strings around, wrap them in classes like `Percent` or `Millions` that encapsulate formatting and null-handling. This improves type safety and centralizes formatting logic. - **Custom query builders are the Laravel-native alternative to repositories** (Early): Override `newEloquentBuilder` on your model to return a custom builder class. This keeps models thin and queries organized without the ceremony of repository interfaces. - **Actions are invokable classes for single-use operations** (Early): Use `__invoke` to create callable classes like `CreateTodoAction`. They're easy to inject, test, and compose—especially when one action needs to call another. - **View Models prepare page-specific data without cluttering controllers** (Early): A View Model exposes public methods that return DTOs or collections, and a base class uses reflection to convert those methods into an array for the frontend. This is especially powerful with Inertia.js. - **States and Transitions replace fragile status strings** (Early): Instead of checking `if ($status === 'draft')`, use dedicated state classes. This makes state logic explicit, type-safe, and easier to extend. - **Organize code by Domains, not by class type** (Middle): Structure folders like `Domain\Subscriber\Models` and `Domain\Shared\Models` instead of `App\Models`. This aligns with DDD's bounded contexts and makes it clear which code belongs to which feature area. - **DTOs via `laravel-data` unify Request, Resource, and Data Transfer** (Middle): One class handles validation rules, request injection, and response serialization. This reduces boilerplate and keeps data contracts consistent across web and API routes. - **Global scopes can enforce user ownership automatically** (Middle): A `UserScope` that adds `whereBelongsTo($user)` to every query simplifies multi-user applications, but be careful—it only works when a request exists, so CLI commands need explicit `user_id` handling. 【Reading Tips】 - **Skim the opening code examples** (~0%–3%): The legacy factory code is meant to show what *not* to do. Focus on the Value Object and cast examples that follow—they're the foundation for everything else. - **Deep-read the Action and View Model chapters** (~13%–19%): These are the most reusable patterns. Pay attention to how Actions are injected and how View Models use reflection—this will save you hours of refactoring later. - **Treat the demo app chapters as a case study** (~19%–48%): Don't get bogged down in every feature detail. Instead, watch how the author decides *where* to put things (Domains, Shared, Actions) and how the patterns interact. - **Watch for the `laravel-data` package specifics** (~32%–42%): The static `rules` method and the `ignore` callback are non-obvious. If you plan to use this package, read these sections carefully. - **Take away the "why" over the "how"**: The author frequently explains *why* he prefers query builders over repositories or DTOs over arrays. These opinions are the real value—they'll help you make your own architectural decisions. 【Coverage Limits】 This guide covers the book's core patterns (Value Objects, Actions, View Models, States, Domains, DTOs, CQRS) and the email marketing demo application. The excerpts do not cover the final chapters on CQRS implementation details, advanced reporting, or deployment concerns—those sections were not included in the source material.
Page 5
ryModel"&getAll();    foreach ($industries as $industry) {      $industryItem = new Search_View_Container_Relation_Item(        $industry, 4 / 258 Martin Joo...
View in text
Excerpt 2
thing. That something, in most cases, is an Eloquent model. So instead of a string, we have a dedicated class. What does a State class look like? Let's say w...
View in text
Excerpt 3
, you need to read a CSV file and write an action for this. What if you need to use this class from many domains? Users I want to clarify one more thing befo...
View in text
Excerpt 4
To; trait HasUser {  public function user(): BelongsTo {    return $this"&belongsTo(User"%class); }  protected static function booted() {    static"%addGloba...
View in text
Excerpt 5
lic function canSend(): bool {    return match ($this) {      self"%Draft ") true,      self"%Sent ") false, } } In the introduction, I talked about states a...
View in text
Excerpt 6
s in the context of subscribers. I need to think about it. Even if it's just one second, it's an extra cognitive load. received_mails . From a technical poin...
View in text
Excerpt 7
ances(): int {    return SentMail"%countOf($this); } } It's a cool technique to remove these kinds of duplications where the difference is only a few lines o...
View in text
Excerpt 8
readable, understandable name instead of technical details. It's reusable. All right, back to automations. So when creating a new subscriber, the action will...
View in text
Tags
AI categories
BackendProgramming LanguageCode
Publisher: Martin Joo
Publish Year: 2022
Language: English
Pages: 259
File Format: PDF
File Size: 4.0 MB
Text Preview (First 20 pages)
Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

Generating text preview…