Laravel API – H??ng d?n t?o RESTful API ??n gi?n v?i Laravel

Laravel API – H??ng d?n t?o RESTful API ??n gi?n v?i Laravel

V?i s? phát tri?n m?nh m? c?a xu h??ng phát tri?n web Single page application, s? d?ng RESTful API là l?a ch?n t?t nh?t. Trong bài vi?t này, chúng ta s? cùng xây d?ng và test m?t API ??n gi?n nh?ng v?n m?nh m? b?ng cách s? d?ng Laravel Framework

Cài ??t Laravel và k?t n?i Database

ch?y l?nh kh?i t?o project laravel (máy ?ã cài composer):

composer create-project --prefer-dist laravel/laravel simpleapi

Trong th? m?c g?c c?a project v?a t?o, m? file .env và nh?p thông tin database:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_name
DB_USERNAME=root
DB_PASSWORD=db_password

Trên terminal, cd vào th? m?c project, t?o server test v?i l?nh sau:

php artisan serve

m? trình duy?t web và ch?y th?: localhost:8000

T?o model và các table

Ch?y l?nh sau ?? t?o Model và migration:

php artisan make:model Post -m

M? file migration v?a t?o trong th? m?c database\migrations và ch?nh s?a ph??ng th?c up():

    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

s?a file migration user có s?n khi t?o project:

database\migrations\2014_10_12_000000_create_users_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('api_token')->unique()->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
};

ch?y l?nh migrate ?? t?o các table:

php artisan migrate

Thêm thu?c tính $fillable vào model Post v?a t?o s? t??ng t? nh? sau:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'content'];
}

T?o d? li?u th? nghi?m

ch?y l?nh sau ?? t?o seeder:

php artisan make:seeder PostTableSeeder

Faker ???c dùng trong các seeder bên d??i là th? vi?n có tác d?ng t?o d? li?u th? nghi?m.

Trong th? m?c database\seeders Ch?nh s?a file PostTableSeeder.php:

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Post;

class PostTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $faker = \Faker\Factory::create();

        for ($i=0; $i < 100; $i++) { 
            Post::create([
                'title' => $faker->sentence,
                'content' => $faker->paragraph
            ]);
        }
    }
}

t??ng t?, t?o seeder cho table users:

php artisan make:seeder UserTableSeeder

Ch?nh s?a file UserTableSeeder.php v?a t?o:

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\User;
use Hash;

class UserTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        User::truncate(); // xóa d? li?u c?

        $faker = \Faker\Factory::create();

        // mã hóa password
        $password = Hash::make('test123');

        User::create([
            'name' => 'Admin',
            'email' => '[email protected]',
            'password' => $password
        ]);

        for ($i=0; $i < 5; $i++) { 
             User::create([
                'name' => $faker->name,
                'email' => $faker->email,
                'password' => $password
            ]);
        }
    }
}

thêm các seeder vào DatabaseSeeder.php

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call([
            PostTableSeeder::class,
            UserTableSeeder::class
        ]);
    }
}

ch?y l?nh insert d? li?u th? nghi?m vào database:

php artisan db:seed

T?o Route, Controller, Request

T?o Request ?? validation

php artisan make:request PostRequest

N?i dung app\Http\Requests\PostRequest.php

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class PostRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        return [
            'title' => 'required|max:150',
            'content' => 'required'
        ];
    }
}

T?o controller:

php artisan make:controller Api/PostController --model=Post

app\Http\Controllers\Api\PostController.php

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return Post::all();
    }


    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(PostRequest $request)
    {
        $post = Post::create($request->all());

        return response()->json($post, 201);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        return $post;
    }


    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(PostRequest $request, Post $post)
    {
        $post->update($request->all());

        return response()->json($post, 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        $post->delete();

        return response()->json(null, 204);
    }
}

Thêm route vào routes\api.php

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\PostController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::apiResource('posts', PostController::class);

Dùng Postman ?? ki?m tra k?t qu?:

H??ng d?n laravel api restful

 

Xác th?c ng??i dùng khi request Api

T?o controller Api/AuthController

php artisan make:controller Api/AuthController
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use Auth;
use Str;

class AuthController extends Controller
{
    public function login(Request $request)
    {
        $info = $request->only(['email','password']);

        if (Auth::attempt($info)) {
            $user = Auth::user();
            $user->api_token = $user->id . Str::random(50);
            $user->save();

            return response()->json($user, 200);
        }
        else {
            return response()->json(['data' => 'Invalid email or password.']);
        }
    }

    public function logout(Request $request)
    {
        if (User::where('api_token', $request->api_token)->update(['api_token' => null])) {
            return response()->json(['data' => 'Logged out.'], 200);
        }
        else {
            return response()->json(['data' => 'logout failed.'], 200);
        }
    }
}

T?o middleware:

php artisan make:middleware CheckApiToken

app\Http\Middleware\CheckApiToken.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\Models\User;

class CheckApiToken
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        if (!empty($request->api_token)) {
            if (User::where('api_token', $request->api_token)->first()) {
                return $next($request);
            }
            else {
                return response()->json(['data' => 'Token is invalid.'], 200);
            }
        }
        else {
            return response()->json(['data' => 'Empty Token.'], 200);
        }
    }
}

Khai báo middleware

M? file app\Http\Kernel.php

tìm ??n thu?c tính $routeMiddleware và khai báo middleware v?a t?o:

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'checkApiToken' => \App\Http\Middleware\CheckApiToken::class
    ];

S?a route, thêm middleware vào các route c?n xác th?c:

routes\api.php

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\PostController;
use App\Http\Controllers\Api\AuthController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::post('login', [AuthController::class, 'login']);

Route::middleware('checkApiToken')->group(function() {
    Route::apiResource('posts', PostController::class);
    Route::post('logout', [AuthController::class, 'logout']);
});

M?i khi request api, c?n ph?i kèm theo api_token, ch?y th? laravel api trên Postman:

Done

5 12 đánh giá
Đánh giá bài viết
Theo dõi
Thông báo của
guest

2 Góp ý
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất
Phản hồi nội tuyến
Xem tất cả bình luận
Nguy?n Hùng
Nguy?n Hùng
2 năm trước

?úng th? mình ?ang c?n, thank ad

Dung Tran
Dung Tran
2 năm trước
Trả lời  Nguy?n Hùng

Ng?n g?n súc tích d? hi?u, d? làm theo