Laravel  ❤️ Startups

Fit to scale?

Luckey Homes

  • Takes the pain out of Airbnb
     
  • Created 18 months ago
     
  • 30+ team
     
  • 5 Laravel developers

Chosing Laravel for your Startup

  • Fast Onboarding
  • Big community
  • Lots of packages

💪🏻 Pros

  • Recruitment in Paris
  • Scalability
    - Architecture?
    - Successful examples?

👎🏻 Cons

=> What would I do differently?

Big app complexity

  • Web
     
  • API
     
  • CLI
  • Sales Module
  • Employee Module
  • MailServer Module
  • PhoneServer Module  
  • BookingManagement Module 
  • Contractor Tasks Module
  • Invoicing Module
  • CashFlow Module
  • Hiring Module
  • LuckeyHomes.com
     
  • Luckey.backend
     
  • Luckey.finance
     
  • Luckey.sales

Good principles to start

 

  • Testing
     
  • Inversion of control & Dependency Injection
     
  • SOLID Principles
     
  • Domain Driven Design
     
  • Makefile + strong CI
  • Lack of resources regarding micro-services in PHP
  • Keeping things clean = significantly increase codebase
  • Dramatically decrease performance (HTTP Layers, Encoding + Decoding)

DDD or Microservices

Great to maintain abstraction and flexibility but...

=> Failure for synchronus micro-services
Still cool for asynchrous ms, replacing the HTTP Layer by a Redis Queue

A new folder structure

---| app
   | domain
   | bootstrap
   | config
   | public
   | tests
   | storage
   | vendor
   | (database)
   | (resources)

The app/ directory

---| app
   | domain
   | bootstrap
   | config
   | public
   | tests
   | storage
   | vendor
   | (database)
   | (resources)

 

  • Laravel specific logic
  • API Logic
  • Shared exceptions
  • Shared abstracts for various components : Raygun, Intercom, Algolia...
    => Never add any business logic here

The domain/ directory

domain -| TaskManagement -| Models
                          | Requests
                          | Jobs
                          | Subscribers
                          | Policies
                          | Mailables
                          | Expose -| API -| Transformers
                                          -| Controllers
                                           routes.php

                                   -| Web -| Views
                                          -| Controllers
                                           routes.php

                                   -| CLI -| Commands

                                   -| Resources -| Mails
                                                -| Middlewares
                                                -| Langs

                          | storage
                          | vendor
                          composer.json

       -| BusinessLogic2 -| ...

Each directory gets a composer.json
+ namespace LuckeyHomes/BusinessLogic
to be switched to a package easily

Tweaking the composer.json

{
    "require": {
        "wikimedia/composer-merge-plugin": "dev-master",
        "twilio/sdk": "^4.5",
        "algolia/algoliasearch-laravel": "^1.0",
        "intercom/intercom-php": "^3.0"
    },
    "scripts": {
        "post-install-cmd": "./scripts/composer-post-install.sh",
        "production-warmup": [
            "php artisan config:cache",
            "php artisan route:cache"
        ]
    },
    "extra": {
        "merge-plugin": {
            "include": [
                "domain/*/composer.json"
            ],
            "require": [
                "submodule/composer.json"
            ],
            "recurse": true,
            "replace": true,
            "merge-dev": true,
            "merge-extra": true,
            "merge-scripts": true
        }
    }
}

Tweaking Laravel core


  • Easy = Put models + controllers + routes
    Into separate folder w/ dedicated service provider

  • Harder = Migrations, Views, Langs...
    ServiceProvider functions: loadViewsFrom, loadTranslationsFrom
  • From Laravel 5.4: loadMigrationsFrom

  • Warning: makes updates more difficult! Breaks auto-updater

Makefiles to bundle it all

FIG=docker-compose 
EXEC=exec --user=laradock workspace sh
EXECB=exec --user=laradock workspace bash

.PHONY: test
test:
	cp .env .env.backup
	cp .env.travis .env
	$(FIG) up -d
	@(if [ "$(filter-out $@,$(MAKECMDGOALS))" = "" ]; \
	then $(FIG) $(EXEC) -c "vendor/bin/codecept run -f"; \
	else $(FIG) $(EXEC) -c "vendor/bin/codecept run -f domain/$(filter-out $@,$(MAKECMDGOALS))/tests/ -f"; fi)
	$(FIG) stop
	mv .env.backup .env

Other learnings

 

  • Updates will be tiresome: chose the LTS version
     
  • Event-driven rather than logic in controller
    (subscribers + abstracts of eloquent.updated: *)
     
  • Cache + compile, Blackfire
     
  • Install an error tracking tool
     
  • Heroku-like paas is nice

Going further

 

  • Publishing to sub-repositories?
     
  • Call service provider only when matching route?
    Load balancer => call the needed part only
     
  • Log flagging
     
  • Serving assets on multiple domains?

deck

By Félix

deck

  • 495