Learn Laravel 8 API Development Tutorial Step by Step using Sanctum Authentication
API is the acronym for Application Programming Interface, which is a software intermediary that allows two applications to talk to each other. Each time you use an app like Facebook, send an instant message or check the weather on your phone, you’re using an API.
Let’s install Laravel 8 via composer. (https://laravel.com/docs/8.x/installation#installation-via-composer)
composer create-project laravel/laravel laravel-api
Now go to the folder and start the server
php artisan serve
Run the following URL to the browser: http://127.0.0.1:8000/
Before getting started let’s understand basic concepts of Laravel .So what is the migration process in Laravel?
php artisan make:migration CreateStudentsTable
Go to the migration file and add the following command.
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;class CreateStudentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string("name",100);
$table->string("email",100);
$table->integer("age")->unsigned();
$table->string("phone_no",20);
$table->enum("gender",["male","female"]);
$table->timestamps();
});
}/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('students');
}
}
Now run the following command.
php artisan migrate
It will create students table in a database.
Laravel artisan command migrate: refresh
This command will only roll back the actual migrations by actually running the down()
methods on all of your migrations, and then migrating from scratch.
Laravel artisan command migrate: rollback
This command is used to undo the last database migration.
Now let’s understand Data Seeders.
So for that let’s create a Model, Seeder, and factory.
php artisan make:model Student -fs
Go to Open StudentSeeder.php from /database/seeders/ and add following code.
<?phpnamespace Database\Seeders;use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;class StudentSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$faker = \Faker\Factory::create();DB::table("students")->insert([
"name" => $faker->name(),
"email" => $faker->safeEmail,
"phone_no" => $faker->phoneNumber,
"age" => $faker->numberBetween(25, 50),
"gender" => $faker->randomElement(["male", "female"])
]);
}
}
Now run the following command to add one data.
php artisan db:seed --class=StudentSeeder
This will add one record to students table. So if you want more records then you need to put such code in the loop.
Now go to StudentFactory.php in /database/factories
<?phpnamespace Database\Factories;use App\Models\Student;
use Illuminate\Database\Eloquent\Factories\Factory;class StudentFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Student::class;/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
"name" => $this->faker->name(),
"email" => $this->faker->safeEmail,
"phone_no" => $this->faker->phoneNumber,
"age" => $this->faker->numberBetween(15, 45),
"gender" => $this->faker->randomElement([
"male",
"female"
])
];
}
}
After this let’ suppose We need 100 dummy data to students table. So go to DatabaseSeeder.php in \database\seeders.
<?phpnamespace Database\Seeders;use Illuminate\Database\Seeder;class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
\App\Models\Student::factory(100)->create();
}
}
Now run seed command.
php artisan db:seed
So 100 students records are inserted.
Now let’s dive into API code. Create ApiController.php in API folder.
php artisan make:controller Api/ApiController
Now go to ApiController.php and add a list of methods we need to develop.
<?phpnamespace App\Http\Controllers\Api;use App\Http\Controllers\Controller;
use Illuminate\Http\Request;class ApiController extends Controller
{
//Create Student
public function CreateStudent(Request $request) {}//List Students
public function listStudents() {}// Single student API
public fucntion getSingleStudent($id) {}// Update Student
public function updateStudent(Request $reques , $id) {}// Delte Student
public function deleteStudent($id) {
}
}
Now create a Model and routes for APIs.
Go to Student.php model
protected $fillable = ["name" , "email" , "phone_no" , "gender" , "age"];
Now go to routes/api.php
<?phpuse Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\ApiController;/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});// API routes
Route::get("list-students", [ApiController::class, "listStudents"]);
Route::get("single-student/{id}", [ApiController::class, "getSingleStudent"]);
Route::post("add-student", [ApiController::class, "CreateStudent"]);
Route::put("update-student/{id}", [ApiController::class, "updateStudent"]);
Route::delete("delete-student/{id}", [ApiController::class, "deleteStudent"]);
Now let’s create Methods in the controller
Add Student: http://127.0.0.1:8000/api/add-student — POST
{
"name" : "First student",
"email" : "test@test.com",
"phone_no" : 1234567890,
"gender" : "male",
"age" : 12
}
List students: http://127.0.0.1:8000/api/list-students — GET
Get Single Student: http://127.0.0.1:8000/api/single-student/20 — GET
Delete Student: http://127.0.0.1:8000/api/delete-student/3 — DELETE
Update Student: http://127.0.0.1:8000/api/update-student/102 — PUT
Now API Development Using Sanctum Authentication.
For this, We will add a projects table again with student id. So let’s create migration for the project table.
php artisan make:migration CreateProjectsTable
Now got to the projects migration file.
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;class CreateProjectsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->id();
$table->integer("student_id")->unsigned();
$table->string("name" , 50);
$table->text("description");
$table->integer("duration");
$table->timestamps();
});
}/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('projects');
}
}
Run the following command.
php artisan migrate
Now create the model.
php artisan make:model Project
Add fillable
protected $fillable = ["name" , "student_id" , "description" , "duration"];
Now create ProjectsController.php
php artisan make:controller Api/ProjectController
php artisan make:controller Api/StudentController
Now install the Sanctum package.
composer require laravel/sanctumphp artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"php artisan migrate
Go to RouteServiceProvider.php and uncomment protected $namespace = ‘App\\Http\\Controllers’;
Add following line to Student and Project Model
use Laravel\Sanctum\HasApiTokens;
use HasFactory , HasApiTokens;
Now create Routes to api.php.
Route::post("register", [StudentController::class, "register"]);
Route::post("login", [StudentController::class, "login"]);Route::group(["middleware" => ["auth:sanctum"]], function(){Route::get("profile", [StudentController::class, "profile"]);
Route::get("logout", [StudentController::class, "logout"]);Route::post("create-project", [ProjectController::class, "createProject"]);
Route::get("list-project", [ProjectController::class, "listProject"]);
Route::get("single-project/{id}", [ProjectController::class, "singleProject"]);
Route::delete("delete-project/{id}", [ProjectController::class, "deleteProject"]);
});
Go to StudentController.php
<?phpnamespace App\Http\Controllers\Api;use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Student;
use Illuminate\Support\Facades\Hash;class StudentController extends Controller
{
// REGISTER API
public function register(Request $request)
{
// validation
$request->validate([
"name" => "required",
"email" => "required|email|unique:students",
"password" => "required|confirmed"
]);// create data
$student = new Student();
$student->name = $request->name;
$student->email = $request->email;
$student->password = Hash::make($request->password);
$student->phone_no = isset($request->phone_no) ? $request->phone_no : "";$student->save();// send response
return response()->json([
"status" => 1,
"message" => "Student registered succesfully"
]);
}// LOGIN API
public function login(Request $request)
{
// validation
$request->validate([
"email" => "required|email",
"password" => "required"
]);// check student
$student = Student::where("email", "=", $request->email)->first();if(isset($student->id)){if(Hash::check($request->password, $student->password)){// create a token
$token = $student->createToken("auth_token")->plainTextToken;/// send a response
return response()->json([
"status" => 1,
"message" => "Student logged in successfully",
"access_token" => $token
]);
}else{return response()->json([
"status" => 0,
"message" => "Password didn't match"
], 404);
}
}else{return response()->json([
"status" => 0,
"message" => "Student not found"
], 404);
}
}
// PROFILE API
public function profile()
{
return response()->json([
"status" => 1,
"message" => "Student Profile information",
"data" => auth()->user()
]);
}// LOGOUT API
public function logout()
{
auth()->user()->tokens()->delete();return response()->json([
"status" => 1,
"message" => "Student logged out successfully"
]);
}
}
Call APIs via followig URLs.
Register — http://127.0.0.1:8000/api/register — POST
{"name" : "First student","email" : "test@test.com1","phone_no" : "1234567891","gender" : "male","age" : 12,"password":"123456","password_confirmation" : "123456"}
Login — http://127.0.0.1:8000/api/login
{"email" : "test@test.com1","password":"123456"}// {"status":1,"message":"Student logged in successfully","access_token":"2|VHVZnWGu8cmZavrPAU9MHeInsRqiIuoPZB4qTMNU"}
Student Profile — GET — http://127.0.0.1:8000/api/profile
Logout — GET — http://127.0.0.1:8000/api/logout (params are same as profile api)
Now let’s make code in ProjectsController.php
<?phpnamespace App\Http\Controllers\Api;use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
Use App\Models\Project;class ProjectController extends Controller
{
// CREATE PROJECT API
public function createProject(Request $request)
{
// validation
$request->validate([
"name" => "required",
"description" => "required",
"duration" => "required"
]);// student id + create data
$student_id = auth()->user()->id;$project = new Project();$project->student_id = $student_id;
$project->name = $request->name;
$project->description = $request->description;
$project->duration = $request->duration;$project->save();// send response
return response()->json([
"status" => 1,
"message" => "Project has been created"
]);
}// LIST PROJECT API
public function listProject()
{
$student_id = auth()->user()->id;$projects = Project::where("student_id", $student_id)->get();return response()->json([
"status" => 1,
"message" => "Projects",
"data" => $projects
]);
}// SINGLE PROJECT API
public function singleProject($id)
{
$student_id = auth()->user()->id;if(Project::where([
"id" => $id,
"student_id" => $student_id
])->exists()){$details = Project::where([
"id" => $id,
"student_id" => $student_id
])->first();return response()->json([
"status" => 1,
"message" => "Project detail",
"data" => $details
]);
}else{return response()->json([
"status" => 0,
"message" => "Project not found"
]);
}
}// DELETE PROJECT API
public function deleteProject($id)
{
$student_id = auth()->user()->id;if(Project::where([
"id" => $id,
"student_id" => $student_id
])->exists()){$project = Project::where([
"id" => $id,
"student_id" => $student_id
])->first();
$project->delete();return response()->json([
"status" => 1,
"message" => "Project has been deleted successfully"
]);}else{return response()->json([
"status" => 0,
"message" => "Project not found"
]);
}
}
}
Craete Project — http://127.0.0.1:8000/api/create-project .Pass token in headers and following to body part.
{"name" : "Prject1","description" : "prkect description","duration" : 10}
List Project — GET — http://127.0.0.1:8000/api/list-project (Pass token to headers)
Single Project — GET — http://127.0.0.1:8000/api/single-project/1 (Pass token to headers)
Delete Project — DELETE — http://127.0.0.1:8000/api/delete-project/1 (Pass token to headers)