Swagger là gì?

Swagger là một Ngôn ngữ mô tả giao diện để mô tả các API RESTful được thể hiện bằng JSON.

Swagger được sử dụng cùng với một bộ công cụ phần mềm mã nguồn mở để thiết kế, xây dựng, lập tài liệu và sử dụng các dịch vụ web RESTful.

Swagger bao gồm tài liệu tự động, tạo mã (sang nhiều ngôn ngữ lập trình) và tạo test-case.

Cài đặt Laravel

Đầu tiên, chúng ta cần tạo một dự án Laravel mới, sử dụng lệnh sau: 

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

Tiếp theo, chúng ta sẽ kết nối với cơ sở dữ liệu như sau:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_swagger
DB_USERNAME=root
DB_PASSWORD=

 Cuối cùng, hãy chạy lệnh sau để tạo cấu trúc bảng cơ sở dữ liệu:

php artisan migrate

Cài đặt Swagger trong Laravel

Đầu tiên, chúng ta sẽ cài đặt thư viện darkaonline/l5-swagger bằng lệnh sau:

composer require "darkaonline/l5-swagger"

Tiếp theo, chúng ta sẽ publish L5-Swagger's config bằng lệnh command sau:

php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"

Để cho dự án Laravel có thể tự động cập nhập lại tài liệu, chúng ta cần thêm cấu hình sau vào file .env

L5_SWAGGER_GENERATE_ALWAYS=true

Nếu không thêm cấu hình ở trên, mỗi khi bạn thay đổi tài liệu, bạn sẽ cần chạy lệnh sau để cập nhật tài liệu:

php artisan l5-swagger:generate

Example Document API

Chúng ta viết tài liệu các API thông qua thư viện swagger-php, vì vậy các bạn cần phải học các cú pháp của thư viện này trước khi thực hiện các ví dụ API bên dưới:

http://zircote.github.io/swagger-php/guide/

Để hiểu rõ hơn nữa, các bạn nên tìm hiểu thêm về OpenAPI, phiên bản mới nhất là 3.0 các bạn hãy nhấp vào URL bên dưới:

https://swagger.io/docs/specification/about/

Thông tin cơ bản API

Đầu tiên bạn mở Controller.php nằm trong thư mục app\Http\Controllers và chỉnh sửa như sau:

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;

class Controller extends BaseController
{
    /**
     * @license Apache 2.0
     */

    /**
     * @OA\Info(
     *     description="This is a sample Userstore server.  You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).",
     *     version="1.0.0",
     *     title="Swagger ManhDanBlogs",
     *     termsOfService="http://swagger.io/terms/",
     *     @OA\Contact(
     *         email="[email protected]"
     *     ),
     *     @OA\License(
     *         name="Apache 2.0",
     *         url="http://www.apache.org/licenses/LICENSE-2.0.html"
     *     )
     * )
     *  @OA\Server(
     *      url="http://127.0.0.1:8000/api/",
     *      description="Development Environment"
     *  )
     *
     *  @OA\Server(
     *      url="http://127.0.0.1:9000/api/",
     *      description="Staging  Environment"
     * )
     * @OA\Tag(
     *     name="auth",
     *     description="Operations about auth user",
     *     @OA\ExternalDocumentation(
     *         description="Find out more about store",
     *         url="http://swagger.io"
     *     )
     * )
     * @OA\Tag(
     *     name="user",
     *     description="Operations about user",
     *     @OA\ExternalDocumentation(
     *         description="Find out more about store",
     *         url="http://swagger.io"
     *     )
     * )
     * @OA\Tag(
     *     name="upload",
     *     description="Operations about file",
     *     @OA\ExternalDocumentation(
     *         description="Find out more about store",
     *         url="http://swagger.io"
     *     )
     * )
     * @OA\ExternalDocumentation(
     *     description="Find out more about Swagger",
     *     url="http://swagger.io"
     * )
     */

    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

CURD Model User

Đầu tiên, bạn hãy mở User.php nằm trong thư mục app\Models và chỉnh sửa như sau:

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /** @OA\Schema(
     *     schema="User",
     *     required={"id", "name", "email", "password"},
     *     @OA\Property(
     *         property="id",
     *         type="integer",
     *         format="int32"
     *     ),
     *     @OA\Property(
     *         property="name",
     *         type="string"
     *     ),
     *     @OA\Property(
     *         property="email",
     *         type="string"
     *     ),
     *     @OA\Property(
     *         property="email_verified_at",
     *         type="string",
     *         format="date-time"
     *     ),
     *     @OA\Property(
     *         property="password",
     *         type="string"
     *     ),
     *     @OA\Property(
     *         property="created_at",
     *         type="string",
     *         format="date-time"
     *     ),
     *     @OA\Property(
     *         property="updated_at",
     *         type="string",
     *         format="date-time"
     *     )
     * ),
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

Tiếp theo, chúng ta sẽ tạo một controller có các chức năng cơ bản như lấy danh sách user, lấy thông tin user, thêm user, sửa user và xóa user. Bạn hãy chạy lệnh command sau:

php artisan make:controller UserController --api

Sau đó bạn hãy mở UserController nằm trong thư mục app\Http\Controllers và chỉnh sửa như sau:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use App\Http\Resources\UserResource;
use App\Http\Resources\UserCollection;
use App\Http\Requests\StoreUserRequest;
use App\Http\Requests\UpdateUserRequest;
use Illuminate\Support\Facades\Hash;

class UserController extends Controller
{
    /**
     * @OA\Get(
     *     path="/users",
     *     tags={"user"},
     *     summary="Get list user",
     *     description="Returns a single new user.",
     *     operationId="getListUser",
     *     @OA\Parameter(
     *         name="name",
     *         in="query",
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Response(
     *          response=200,
     *          description="successful operation",
     *          @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="data",
     *                  type="array",
     *                  @OA\Items(
     *                      type="object",
     *                      example={
     *                          "id": 1,
     *                          "name": "ManhDan",
     *                          "email": "[email protected]",
     *                      },
     *                  )
     *              ),
     *              @OA\Property(
     *                  property="links",
     *                  type="object",
     *                  example={
     *                      "first": "http://127.0.0.1:8000/api/users?page=1",
     *                      "last": "http://127.0.0.1:8000/api/users?page=1",
     *                      "prev": null,
     *                      "next": null,
     *                  },
     *              ),
     *               @OA\Property(
     *                  property="meta",
     *                  type="object",
     *                  @OA\Property(
     *                      property="current_page",
     *                      type="integer",
     *                      example=1
     *                  ),
     *                  @OA\Property(
     *                      property="from",
     *                      type="integer",
     *                      example=1
     *                  ),
     *                  @OA\Property(
     *                      property="last_page",
     *                      type="integer",
     *                      example=1
     *                  ),
     *                  @OA\Property(
     *                      property="links",
     *                      type="array",
     *                      @OA\Items(
     *                          type="object",
     *                          example={
     *                              "url": "http://127.0.0.1:8000/api/users?page=1",
     *                              "label": "http://127.0.0.1:8000/api/users?page=1",
     *                              "active": null,
     *                          },
     *                      )
     *                  ),
     *                  @OA\Property(
     *                      property="path",
     *                      type="string",
     *                      example="http://127.0.0.1:8000/api/users"
     *                  ),
     *                  @OA\Property(
     *                      property="per_page",
     *                      type="integer",
     *                      example=10
     *                  ),
     *                  @OA\Property(
     *                      property="to",
     *                      type="integer",
     *                      example=10
     *                  ),
     *                  @OA\Property(
     *                      property="total",
     *                      type="integer",
     *                      example=10
     *                  ),
     *              ),
     *          )
     *      ),
     * )
     */
    public function index()
    {
        $users = User::select(['id', 'name', 'email'])->paginate(10);
        return new UserCollection($users);
    }

    /**
     * @OA\Post(
     *     path="/users",
     *     tags={"user"},
     *     summary="Add a new user to the store",
     *     description="Returns a single new user.",
     *     operationId="createUser",
     *     @OA\RequestBody(
     *          description= "User object that needs to be added to the store",
     *          required=true,
     *          @OA\JsonContent(
     *              type="object",
     *              @OA\Property(property="name", type="string"),
     *              @OA\Property(property="email", type="string"),
     *              @OA\Property(property="password", type="string")
     *          )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="successful operation",
     *         @OA\JsonContent(ref="#/components/schemas/User"),
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Invalid id supplied",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="The specified data is invalid."
     *              ),
     *              @OA\Property(
     *                  property="errors",
     *                  type="object",
     *                  example={
     *                      "name": "The name field is required.",
     *                  },
     *              ),
     *         ),
     *     ),
     * )
     */
    public function store(StoreUserRequest $request)
    {
        $data             = $request->all();
        $data['password'] = Hash::make($request->password);
        $user             = User::create($data);
        return new UserResource($user);
    }

    /**
     * @OA\Get(
     *     path="/users/{userId}",
      *    tags={"user"},
     *     summary="Get user by user id",
     *     operationId="getUserById",
     *     description="Returns a single user.",
     *     @OA\Parameter(
     *         name="userId",
     *         in="path",
     *         required=true,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="successful operation",
     *         @OA\JsonContent(ref="#/components/schemas/User"),
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="User not found",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="User not found."
     *              ),
     *         ),
     *     ),
     * )
     */
    public function show($id)
    {
        $user = User::where('id', $id)->first();
        if ($user) {
            return new UserResource($user);
        }
        return response()->json(['message' => 'User not found.'], JsonResponse::HTTP_NOT_FOUND);
    }

    /**
     * @OA\Put(
     *     path="/users/{userId}",
     *     tags={"user"},
     *     summary="Updated user",
     *     description="Returns a single user.",
     *     operationId="updateUser",
     *     @OA\Parameter(
     *         name="userId",
     *         in="path",
     *         description="User that to be updated",
     *         required=true,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\RequestBody(
     *          description= "User object needs to be updated to the store.",
     *          required=true,
     *          @OA\JsonContent(
     *              type="object",
     *              @OA\Property(property="email", type="string"),
     *              @OA\Property(property="password", type="string")
     *          )
     *     ),
     *      @OA\Response(
     *          response=200,
     *          description="successful operation",
     *          @OA\JsonContent(
     *              type="object",
     *              @OA\Property(property="email", type="string"),
     *              @OA\Property(property="name", type="string"),
     *          )
     *      ),
     *     @OA\Response(
     *         response=400,
     *         description="Invalid id supplied",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="The specified data is invalid."
     *              ),
     *              @OA\Property(
     *                  property="errors",
     *                  type="object",
     *                  example={
     *                      "name": "The name field is required.",
     *                  },
     *              ),
     *         ),
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="User not found",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="User not found."
     *              ),
     *         ),
     *     )
     * )
     */
    public function update(UpdateUserRequest $request, $id)
    {
        $user = User::where('id', $id)->first();
        if ($user) {
            $user->email    = $request->email;
            $user->password = $request->password;
            $user->save();
            return response()->json(['message' => 'Update user successfully.'], JsonResponse::HTTP_OK );
        }
        return response()->json(['message' => 'User not found.'], JsonResponse::HTTP_NOT_FOUND);
    }

    /**
     * @OA\Delete(
     *     path="/users/{userId}",
     *     tags={"user"},
     *     summary="Delete user",
     *     description="This can only be done by the logged in user.",
     *     operationId="deleteUser",
     *     @OA\Parameter(
     *         name="userId",
     *         in="path",
     *         description="The name that needs to be deleted",
     *         required=true,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="successful operation",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="Delete user successfully."
     *              ),
     *         ),
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="User not found",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="User not found."
     *              ),
     *         ),
     *     )
     * )
     */
    public function destroy($id)
    {
        $user = User::where('id', $id)->first();
        if ($user) {
            $user->delete();
            return response()->json(['message' => 'Delete user successfully.'], JsonResponse::HTTP_OK );
        }
        return response()->json(['message' => 'User not found.'], JsonResponse::HTTP_NOT_FOUND);
    }
}

Authentication

Đầu tiên, chúng ta sẽ tạo một controller có các chức năng cơ bản như đăng nhập và lấy thông tin user đang đăng nhập. Bạn hãy chạy lệnh command sau:

php artisan make:controller AuthController

Sau đó bạn hãy mở AuthController.php nằm trong thư mục app\Http\Controllers và chỉnh sửa như sau:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests\LoginAuthRequest;
use App\Http\Resources\UserResource;

class AuthController extends Controller
{
    /**
     * @OA\Post(
     *     path="/login",
     *     tags={"auth"},
     *     summary="Logs user into system",
     *     description="Returns a info auth.",
     *     operationId="loginUser",
     *     @OA\Parameter(
     *         name="email",
     *         in="query",
     *         description="The user name for login",
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="password",
     *         in="query",
     *         @OA\Schema(
     *             type="string",
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="successful operation",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="data",
     *                  type="object",
     *                  example={
     *                     "access_token": "5|Fh33EyADXaSYGIZM518zxBBQXL2aT7jOV9xyXTpJ",
     *                     "token_type": "Bearer",
     *                  },
     *              ),
     *         ),
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Invalid id supplied",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="The specified data is invalid."
     *              ),
     *              @OA\Property(
     *                  property="errors",
     *                  type="object",
     *                  example={
     *                      "email": "The email field is required.",
     *                  },
     *              ),
     *         ),
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="Unauthenticated."
     *              ),
     *         ),
     *     )
     * )
     */
    public function login(LoginAuthRequest $request)
    {
        if (!Auth::attempt($request->only('email', 'password'))) {
            return response()->json(['message' => 'Unauthenticated.'], 401);
        }
        $user  = User::where('email', $request['email'])->firstOrFail();
        $token = $user->createToken('auth_token')->plainTextToken;
        $result['data'] = [
           'access_token' => $token,
           'token_type' => 'Bearer',
        ];
        return response()->json($result);
    }

    /**
     * @OA\Get(
     *     path="/me",
      *    tags={"auth"},
     *     summary="Get user by user id",
     *     operationId="getUserLogined",
     *     description="Returns a single user.",
     *     security={ {"sanctum": {}, "basic_authentication": {} }},
     *     @OA\Response(
     *         response=200,
     *         description="successful operation",
     *         @OA\JsonContent(ref="#/components/schemas/User"),
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="Unauthenticated."
     *              ),
     *         ),
     *     ),
     * )
     */
    public function me(Request $request)
    {
        $user = $request->user();
        return new UserResource($user);
    }
}

Cuối cùng, bạn hãy mở l5-swagger.php nằm trong thư mục config và chỉnh sửa như sau:

...
'securitySchemes' => [
    ...
    'sanctum' => [
        'type' => 'http',
        'description' => 'Laravel Sanctum token authentication',
        'scheme' => 'bearer',
        'bearerFormat' => 'JWT'
    ],
    ...
],
...

Nếu bạn có sử dụng Basic Authentication, bạn hãy mở l5-swagger.php nằm trong thư mục config và chỉnh sửa như sau:

...
'securitySchemes' => [
    ...
    'basic_authentication' => [
        'type' => 'http',
        'description' => 'Basic Authentication is a method for an HTTP user agent (e.g., a web browser) to provide a username and password when making a request.',
        'scheme' => 'basic',
    ],
    ...
],
...

Upload File

Đầu tiên, chúng ta sẽ tạo một controller có các chức năng cơ bản như upload one file và upload multiple file. Bạn hãy chạy lệnh command sau:

php artisan make:controller UploadController

Sau đó bạn hãy mở UploadController.php nằm trong thư mục app\Http\Controllers và chỉnh sửa như sau:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\JsonResponse;

class UploadController extends Controller
{
    /**
     * @OA\Post(
     *     path="/upload/file",
      *    tags={"upload"},
     *     summary="Upload files to the system.",
     *     operationId="uploadFile",
     *     description="Return path file on the system.",
     *     @OA\RequestBody(
     *          required=true,
     *          @OA\MediaType(
     *              mediaType="multipart/form-data",
     *              @OA\Schema(
     *                  @OA\Property(property="file", type="string", format="binary"),
     *              )
     *          )
     *      ),
     *     @OA\Response(
     *         response=200,
     *         description="successful operation",
     *         @OA\JsonContent(ref="#/components/schemas/User"),
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="User not found",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="User not found."
     *              ),
     *         ),
     *     ),
     * )
     */
    public function index(Request $request)
    {
        try {
            $name = $this->setNameFile($request->file->extension());
            $path = $request->file->storeAs('files', $name, 'public');
            return new JsonResponse(['path' => '/' . $path], 200);
        } catch (\Throwable $th) {
            report($th);
            throw new HttpResponseException(
                response()->json([
                    'message' => 'The given data was invalid.',
                    'errors'  => [
                        'file' => $th->getMessage(),
                    ]
                ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY)
            );
        }
    }

    /**
     * @OA\Post(
     *     path="/upload/multiple-file",
      *    tags={"upload"},
     *     summary="Upload files to the system.",
     *     operationId="uploadMultipleFile",
     *     description="Return path file on the system.",
     *     @OA\RequestBody(
     *          @OA\MediaType(
     *              mediaType="multipart/form-data",
     *              @OA\Schema(
     *              type="object",
     *                  @OA\Property(
     *                      property="files[]",
     *                      type="array",
     *                      @OA\Items(type="string", format="binary")
     *                  )
     *              )
     *          )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="successful operation",
     *         @OA\JsonContent(ref="#/components/schemas/User"),
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="User not found",
     *         @OA\JsonContent(
     *              type="object",
     *              @OA\Property(
     *                  property="message",
     *                  type="string",
     *                  example="User not found."
     *              ),
     *         ),
     *     ),
     * )
     */
    public function multiple(Request $request)
    {
        try {
            $result = [];
            foreach ($request->file('files') as $key => $file) {
                $name = $this->setNameFile($file->extension());
                $path = $file->storeAs('files', $name, 'public');
                array_push($result, '/' . $path);
            }
            return new JsonResponse($result, 200);
        } catch (\Throwable $th) {
            report($th);
            throw new HttpResponseException(
                response()->json([
                    'message' => 'The given data was invalid.',
                    'errors'  => [
                        'file' => $th->getMessage(),
                    ]
                ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY)
            );
        }
    }

    /**
     * Create new name file.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $response
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    protected function setNameFile($extension)
    {
        $time     = time();
        $str_rand = \Str::random(12);
        return "{$str_rand}_{$time}.{$extension}";
    }
}

Trải nghiệm Swagger Laravel

Các bạn hãy truy cập vào URL sau để trải nghiệm Swggwer trong Laravel nào.

http://127.0.0.1:8000/api/documentation

Như vậy, mình đã hướng dẫn các bạn cách cài đặt swagger trong dự án Laravel, mình hy vọng bài viết này sẽ giúp ích cho công việc và quá trình học tập của bạn. Nếu bạn có bất kỳ câu hỏi nào hãy liên hệ với chúng tôi qua trang contact. Cảm ơn bạn.

CÓ THỂ BẠN QUAN TÂM

Integrating CKFinder with Amazon S3 in Laravel

Integrating CKFinder with Amazon S3 in Laravel

CKFinder 3 CKFinder 3 là trình quản lý tập tin được tích hợp với CKEditor 4 và CKEditor 5. Nó giúp bạn dễ dàng đưa các tập tin và hình ảnh vào nội dung của Editor một cách an toàn. Đây là một tín...

Integrating CKEditor 5 in Laravel 10 using Vite

Integrating CKEditor 5 in Laravel 10 using Vite

CKEditor 5CKEditor 5 là một trình soạn thảo văn bản phong phú JavaScript với nhiều tính năng và khả năng tùy chỉnh. CKEditor 5 có kiến trúc MVC hiện đại, mô hình dữ liệu tùy chỉnh và DOM ảo, mang...

Integrating CKFinder into CKEditor 5 in Laravel 11

Integrating CKFinder into CKEditor 5 in Laravel 11

CKEditor 5 CKEditor 5 là một trình soạn thảo văn bản phong phú JavaScript với nhiều tính năng và khả năng tùy chỉnh. CKEditor 5 có kiến trúc MVC hiện đại, mô hình dữ liệu tùy chỉnh và DOM ảo, mang...

Laravel UI Custom Email Password Reset Template

Laravel UI Custom Email Password Reset Template

Nếu bạn đang dùng thư viện laravel/ui để làm các chức năng liên quan đến authentication, và trong dự án của bạn, bạn cần thay đổi template email password reset thay vì sử dụng template email password...

Laravel Custom Request

Laravel Custom Request

Nếu bạn có một form để người dùng nhập dữ liệu và bạn muốn kiểm tra dữ liệu đầu vào trước khi lưu xuống database chẳng hạn thì bạn có 2 cách sau đây: Cách 1: Bạn thêm validate trực tiếp vào hàm sto...

Laravel UI Password Reset Expired

Laravel UI Password Reset Expired

Trong thư viện laravel/ui, thì chức năng password reset dù cho token có hết hạn thì vẫn có truy cập vào trang password reset, đến khi bạn submit form thì mới thông báo là token đã hết hạn. Nhưng có mộ...

ZSH-Artisan CLI and Docker: The Perfect Match for Laravel Development

ZSH-Artisan CLI and Docker: The Perfect Match for Laravel Development

Zsh Zsh viết tắt của “ Z Shell ” là một shell nâng cao cho hệ thống Unix và Linux. Nó được phát triển nhằm cung cấp các tính năng và khả năng cao hơn so với shell mặc định trên hầu hết các hệ thố...

Google Drive as Filesystem in Laravel

Google Drive as Filesystem in Laravel

Đối với một số dự án, bạn cần phải sử dụng Google Drive (với tài khoản @gmail.com cá nhân hoặc tài khoản G Suite) làm nhà cung cấp bộ nhớ trong các dự án Laravel. Trong bài đăng này, tôi sẽ hướng d...

Laravel  Scout Full Text Search with Algolia

Laravel Scout Full Text Search with Algolia

Laravel Scout cung cấp một giải pháp đơn giản, dựa trên trình điều khiển để thêm tìm kiếm Full Text vào các mô hình Eloquent của bạn. Khi sử dụng Eloquent, Scout sẽ tự động giữ chỉ mục tìm kiếm của bạ...

ManhDanBlogs