« How to build a GraphQL Server using Laravel - Part 2
August 14, 2019 • ☕️ 3 min read
In the first part of this series, we looked at what GraphQL is, it’s advantages and even compared it with REST and SOAP. In this part of the series, we would setup a Laravel project, on top of which our GraphQL server would sit.
As mentioned in the previous article, this series is divided into 3 parts:
- Part 1: What is GraphQL and it’s advantages? GraphQl vs REST
- Part 2: Setup our Laravel Project
- Part 3: Setup our GraphQL Server & Playground in our project
What we’ll be building
In this project we’ll be building an API for a micro blog with which users
can write articles
. Furthermore, we would restrict certain features or functionality to only authenticated users.
Prerequisites
To follow through this article, you’ll need the following installed on your machine:
Creating the Project
To begin, let’s create a new Laravel project via Composer by executing command below in our terminal:
1composer create-project --prefer-dist laravel/laravel laravel-graphql-blog
The command above tells Composer to create a Laravel project named
laravel-graphql-blog
.
The result is a new directory called laravel-graphql-blog
inside the folder we ran the composer create
command. Don’t worry if you are new to Laravel’s structure. You will learn the role of the most important directories and files as we build or you can head over to the official documentation here.
Just to make sure we have everything working, run the commands below in your terminal to boot up our server:
1cd laravel-graphql2php artisan serve
To make sure everything runs well, open
http://localhost:8000
in your browser and you should see Laravel’s default page.
Setting up our Database
Now, open the .env
file (which resides in the project’s root) and configure the database parameters shown below accordingly to your development environment:
1DB_CONNECTION=mysql2DB_HOST=127.0.0.13DB_PORT=33064DB_DATABASE=homestead5DB_USERNAME=homestead6DB_PASSWORD=secret
Note: The above assumes you have already created a MySQL database for this project.
Creating our Models and Migrations
Laravel by default ships with a user model and it’s migration file. We would want to include an api_token
column to our User migration file for our api authentication therefore, let’s edit out this migration:
1// database/migrations/2014_10_12_000000_create_users_table.php23<?php45use Illuminate\Support\Facades\Schema;6use Illuminate\Database\Schema\Blueprint;7use Illuminate\Database\Migrations\Migration;89class CreateUsersTable extends Migration10{11 /**12 * Run the migrations.13 *14 * @return void15 */16 public function up()17 {18 Schema::create('users', function (Blueprint $table) {19 $table->bigIncrements('id');20 $table->string('name');21 $table->string('email')->unique();22 $table->timestamp('email_verified_at')->nullable();23 $table->string('api_token', 80)->unique()->nullable()->default(null);24 $table->string('password');25 $table->rememberToken();26 $table->timestamps();27 });28 }2930 /**31 * Reverse the migrations.32 *33 * @return void34 */35 public function down()36 {37 Schema::dropIfExists('users');38 }39}
Voila! Now, let’s create an Article model and its corresponding migration file. To do that, run the command below in the terminal:
1php artisan make:model Article -m
The command above after creating the Article model, thanks to the -m flag, would create it’s associated migration script.
A migration script defines the table structure needed to persist data in a database.
The Article model is implemented in the Article.php
file that you will find inside the app
directory. In fact, the app
directory contains the code representing the application’s domain.
Once that’s done, open the migration file that was generated and update it’s up method as below:
1// database/migrations/2019_08_08_000000_create_articles_table.php23/**4* Run the migrations.5*6* @return void7*/8public function up()9{10 Schema::create('articles', function (Blueprint $table) {11 $table->bigIncrements('id');12 $table->unsignedBigInteger('user_id');13 $table->string('title');14 $table->text('content');15 $table->timestamps();1617 // User ID foreign Key18 $table->foreign('user_id')->references('id')->on('users');19 });20}
In the above migration file, we added a
foreign key
pointing to theid
on ourusers table
as well as thetitle
andcontent
columns.Note: The up method is used to add new tables, columns, or indexes to your database, while the down method should reverse the operations performed by the up method.
Now, let’s run the migration by executing the command below in the terminal:
1php artisan migrate
Define relationships between models
Next, let’s define the relationships between our models. Take note, we’ll be defining only the necessary parts of the relationships needed for the purpose of this tutorial.
To do so, let’s update our models by defining the necessary relationships starting with our User Model:
1// app/User.php23<?php45namespace App;67use Illuminate\Notifications\Notifiable;8use Illuminate\Contracts\Auth\MustVerifyEmail;9use Illuminate\Foundation\Auth\User as Authenticatable;1011class User extends Authenticatable12{13 use Notifiable;1415 /**16 * The attributes that are mass assignable.17 *18 * @var array19 */20 protected $fillable = [21 'name', 'email', 'password',22 ];2324 /**25 * The attributes that should be hidden for arrays.26 *27 * @var array28 */29 protected $hidden = [30 'password', 'remember_token',31 ];3233 /**34 * The attributes that should be cast to native types.35 *36 * @var array37 */38 protected $casts = [39 'email_verified_at' => 'datetime',40 ];4142 /**43 * @return \Illuminate\Database\Eloquent\Relations\HasMany44 */45 public function articles()46 {47 return $this->hasMany(Article::class);48 }49}
The relationship between a
User
and anArticle
, will be a one-to-many relationship. That is, a user can write as many articles as they wish but
an article can only belong to one user.
Let’s define the inverse of the relationship on the Article model:
1// app/Article.php23<?php45namespace App;67use Illuminate\Database\Eloquent\Model;89class Article extends Model10{11 /**12 * The attributes that are mass assignable.13 *14 * @var array15 */16 protected $fillable = [17 'user_id', 'title', 'content'18 ];1920 /**21 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo22 */23 public function user()24 {25 return $this->belongsTo(User::class);26 }27}
One may ask, how is the
Article
model defined inapp/Article.php
linked to thearticles table
in our database. This happens because, by convention, Eloquent maps a model to a table having the same lowercase name in the plural.
Setting Database seeders
To test the API we are about to create, we need to have some data to work with. To do this, let’s create a database seeder to populate the tasks table with some data.
We’ll start by creating some seeder classes for our users
table. To do that, let’s run the command below in the terminal:
1php artisan make:seeder UsersTableSeeder
Seeders are classes that populate database tables with some data.
The command above will generate a new file called UsersTableSeeder.php
file in database/seeds
directory. Now let’s update it with with the following:
1// database/seeds/UsersTableSeeder.php23<?php45use App\User;6use App\Article;7use Illuminate\Database\Seeder;89class UsersTableSeeder extends Seeder10{11 /**12 * Run the database seeds.13 *14 * @return void15 */16 public function run()17 {18 $faker = \Faker\Factory::create();1920 User::create([21 'name' => $faker->name,22 'email' => 'me@mygraphqlapp.com',23 'password' => bcrypt('secret')24 ]);2526 factory(User::class, 50)->create()->each(function($user) use ($faker){27 for ($i=0; $i < 5; $i++) {28 Article::create([29 'user_id' => $user->id,30 'title' => $faker->sentence,31 'content' => $faker->paragraphs(3,true),32 ]);33 }34 });35 }36}
In the above code, our
UsersTableSeeder
would first create aUser
with a random name but with an email ofme@mygraphqlapp.com
and password ofsecret
.Furthermore, using our default
User
factories which is located in thedatabase/factories
directory, we create50 dummy users
and for each one of these50 users
,5 dummy articles
are created under them.
To run our UsersTableSeeder
let’s update our DatabaseSeeder.php
file database/seeds
directory with the code below;
1// database/seeds/UsersTableSeeder.php23<?php45use Illuminate\Database\Seeder;67class DatabaseSeeder extends Seeder8{9 /**10 * Seed the application's database.11 *12 * @return void13 */14 public function run()15 {16 $this->call(UsersTableSeeder::class);17 }18}
Finally, let’s go ahead and run our database seeders to get some data into our database by running the command below in the terminal:
1php artisan db:seed
Conclusion
That’s all for this part of the series. In this article, we’ve learn’t how to setup a Laravel project and created a micro blog. We’ve only setup up our Laravel project and in the next part of the series, which is the last part, we would be building out our GraphQL API.
Feel free to hit me up with your views, comments or questions. Stay tuned!