The last time Hackerfall tried to access this page, it returned a not found error. A cached version of the page is below, or clickhereto continue anyway

Validating JSON schema with Riemann Medium

Multi-tenant saas api using laravelSettingUp

Before we embark on this journey of learning how to build a laravel restful api for a multi-tenant saas app, we need to set up our local environment. The goal is to start as simple as possible and help you get there step by step. If you are in a hurry, skip the the TLDR section at the bottom for a summary of the steps.

Part 1: Creating theproject

1.1 Prerequisites

You must have composer to be able to go through this tutorial. If you are using homestead youre good to go. For other requirements refer to the laravel docs. To install composer, check out for details.

Over and above these, you need to have a basic knowledge on Laravel. If you dont Laracasts are a good place to start. Ive also not mentioned the rather obvious tools like an editor and terminal which you should already have.

1.2 InstallingLaravel

The next step is to install laravel. This should be pretty easy with composer. In terminal, run the following code

composer create-project laravel/laravel project-api

This will install laravel in the folder project-api, which is what we are building. Didnt know that? Check out the intro post.

For other ways to install laravel, checkout the laravel documentation

1.3 Initiate VersionControl

Great! We now have a vanilla copy of laravel. Before we do any edits, lets commit our current state. Committing now will help us track our changes easily at a later stage. In terminal run,

cd project-apigit initgit add .git commit -am "initial commit"

1.4 Add laravel-ide-helper

Next up, lets add our first package. One of the most important packages for me personally is Barry vd. Heuvels Laravel-ide-helper. This package adds proper autocompletion for your laravel facades and other classes in most decent IDEs. Say goodbye to getting Route::getFacadeAccessor() when trying to type Route::get(). Enough said, lets install it.

In terminal run:

composer require --dev barryvdh/laravel-ide-helper

As youve probably noticed. Weve specified that the package should be added as a dev dependency. This is because we only need it while developing. Theres no need of clogging our production server with unnecessary packages. Therefore, we cant add it to the usual providers list in config/app.php as it will break in production when we run composer install --no-dev. Instead we register it within our AppServiceProvider. Open the file app/Providers/AppServiceProvider.php and add the following code within the register method

if ($this->app->environment() == 'local') {     $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);}

We are checking if the environment is local before registering the package. I do this instead of checking!production because I dont need it in our staging server either only when working locally.

To finish setting it up, run:

php artisan clear-compiledphp artisan ide-helper:generate

Awesome, now lets save our changes by committing to git

git add _ide_helper.phpgit commit -am "add ide-helper"

1.5 Add dingo/api

Now lets add dingo/api. This package will provide us with a set of tools that we can use to develop our api. These range from rate limiting, conditional requests, fractal transformers to mention a few. For more details, check it out at At the time of writing, this package is still in beta so you should not have your composer.json file set to minimum stability: stable

To install run:

composer require dingo/api:[email protected]

In config/app.php add the provider class


and facade

'API' => Dingo\Api\Facade\API::class

In terminal, run

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"

to publish the config then update your.env file to:


It is wise to also update the example env file for future reference. In.env-example add:


Finally, lets commit to git

git add config/api.phpgit commit -am "add dingo/api"

6. Add laravel-cors

To allow javascript users access to our api, we need to enable cross-origin resource sharing. From wikipedia, CORS defines a way in which a browser and server can interact to determine safely whether or not to allow the cross-origin request. Again Barry has another package that helps deal with cors automatically so we never have to worry about it. Dont you just love the guy.

To install it run:

composer require barryvdh/laravel-cors

Add the provider in config/app.php


To publish the config file, run

php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"

Then add a new middleware to the api group in app/Http/Kernel.php


Your api group should look like so

'api' => [    \Barryvdh\Cors\HandleCors::class,    'throttle:60,1',    'bindings',]

Finally, lets commit our changes to git

git add config/cors.php git commit -am "add laravel-cors"

1.7 Add restful-api-helper

The last package for this tutorial is our very own restful-api-helper. Thanks to Samuel Kubai and the team, you can now generate migrations with schemas, model relationships, repositories, transformers and even a complete resource from the comfort of your terminal. Oh and you can customize how they look and where they should be stored. Isnt that just awesome. A round of applause for Sam and his team!

To install it, run

composer require --dev ralphowino/restful-api-helper:1.0.x-dev

Again since we only need it during active development, well add it as a dev dependency.

Well need to update app/Providers/AppServiceProvider.phps register method. Add the service provider


The method should now look as follows

public function register(){           if ($this->app->environment() == 'local') {        $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);         $this->app->register(\Ralphowino\ApiStarter\ApiStarterServiceProvider::class);    }}

To publish the config and templates, run:

php artisan vendor:publish --provider="Ralphowino\ApiStarter\ApiStarterServiceProvider"

Finally, commit your changes

git add config/starter.php templatesgit commit -am "add restful-api-helper"

Alls set now we can start hacking away!!

Part 2: Personal preferences

Like every developer, we have some personal preferences and tools that we like using while building our apis. This section is about what we use at Ralphowino Consulting.



First off, you cant develop an api without postman. Postman allows you to send requests with great easy, making your development process enjoyable and fast. You could use curl but we all know the challenges of working with it. Install postman today and I promise youll forget a life without it. Get it at Throughout this series we shall assume youre using it.


We all have our IDE preference, ours is IntelliJs Phpstorm. If you use this, you should also get the laravel plugin as it helps improve your workflow. There is a laracast series on how to use it should you need a quick intro.


This is deployment tool written in php and runs from your command line. You can setup your deployment process using recipes that extend other already existing recipes such as the laravel recipe. For more info, check out

B. Environment


We like using homestead/vagrant instead of installing a server/php/mysql directly on our machines. It helps separate concerns. We also keep one vm per client instead of 1 vm for all our development work (ends up being clogged up and slow ) or 1 vm per project (you end up with so many instances that its hard keeping track of them). Within my projects folder youll find client-name/vm folders which I use use composer to manage. For this series I have a folder tutorials/vm and tutorials/project-api which is symlinked into the vm. Im a fan of phpmyadmin so I always install that by default some guys prefer sequel pro and workbench.

ii) Configuration

For apis I like having the following environment settings


Our apis are stateless and whatever is stored in session gets discarded after the response is sent back and the connection ended. Seems pointless to store the session details for longer than the connection.


I find this easy to setup and track. There are definitely better queue managers available within laravel. For development I mostly find myself switching between database and sync(for debugging).


We all miss the app/Models folder previously in laravel 4. Personally, I find models in the app folder messy and since they are part of our Data layer, we prefer storing them in app/Data/Models while Repositories go into the app/Data/Repositories. I would then have app/Data/Repositories/Contracts keep the interfaces and app/Data/Repositories/Eloquent to store my Eloquent implementations.

As I mentioned these are personal preferences developed from our experiences while developing the various apis weve worked on. Id love to hear more about how you setup for your projects.


To recap, weve simply set up our project in readiness for coding. You can get the source code at For a quick setup guide follow these instructions:

Install composer and postman(optional)

In terminal, run the following commands

composer create-project laravel/laravel project-api cd project-api git init git add . git commit -am "initial commit"composer require dingo/api:[email protected] barryvdh/laravel-cors composer require --dev barryvdh/laravel-ide-helper ralphowino/restful-api-helper:1.0.x-dev

In config/app.php add providers

Dingo\Api\Provider\LaravelServiceProvider::class, Barryvdh\Cors\ServiceProvider::class,

and facade

'API' => Dingo\Api\Facade\API::class,

In app/Providers/AppServiceProvider.php within the register method add the following code

if ($this->app->environment() == 'local') {    $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);     $this->app->register(\Ralphowino\ApiStarter\ApiStarterServiceProvider::class); }

In terminal run

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider" php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider" php artisan vendor:publish --provider="Ralphowino\ApiStarter\ApiStarterServiceProvider" php artisan clear-compiled php artisan ide-helper:generate

Add to.env and.env-example


In app/Http/Kernel.php add \Barryvdh\Cors\HandleCors::class, within api array in $middlewareGroups

Finally commit your changes

git add . git commit -am "add packages"

And youre all set.

Next Topic: Setting up multi-tenancy

In the next topic, well look at how to set up multi-tenant support for our saas app. Well start by setting up auth and a simple tenant specific resource then implement two tenancy models: tenant_id as a key in the table vs tenant specific tables/database while looking at the pros and cons of each. Keep tuned! Dont forget to share

Next publication date: 14th Sept

Continue reading on