Middleware là gì? Tìm hiểu về Middleware và tự tạo một middleware tùy chỉnh

Middleware là gì?

Middleware là những đoạn mã trung gian nằm giữa các request và response. Nó nhận các request, thi hành các mệnh lệnh tương ứng trên request đó. Sau khi hoàn thành nó response (trả về) hoặc chuyển kết quả ủy thác cho một Middleware khác trong hàng đợi.

Middleware là gì

Ứng dụng Middleware là gì?

Hiện nay các Web Framework tân tiến đều sử dụng nó như là một phần của ứng dụng để kết nối các phần khác lại với nhau. Đối với các ứng dụng web, việc sử dụng Middleware một cách hiệu quả giúp chúng ta có thể tối giản được số lượng dòng code phải viết trong ứng dụng.

Một ví dụ phổ biến mà chúng ta thường phải dùng Middleware đó là các trang chỉ dành riêng cho admin và không cho phép người dùng bình thường có thể truy cập.

Tại sao nên sử dụng nó?

  Expressjs là gì? Tất tần tật về Express.js

Với tư tưởng chung là cầu nối giữa tương tác của người dùng và hệ thống trong lập trình Web. Middleware sẽ đóng vai trò trung gian giữa request/response và các xử lý logic bên trong web server.

Do đó, Middleware trong các Framework cho ứng dụng Web (Laravel, Django, Rails, ExpressJS…), sẽ là các hàm được dùng để tiền xử lý, lọc các request trước khi đưa vào xử lý logic hoặc điều chỉnh các response trước khi gửi về cho người dùng.

Hiểu các khái niệm cơ bản của Laravel Middleware

Trong bài viết này, mình sẽ lấy ví dụ là dùng framework Laravel để hiểu khái niệm về middleware. Chúng ta sẽ xem xét cách tạo middleware tùy chỉnh trong một ứng dụng Laravel.

Sau khi tạo middleware tùy chỉnh của bạn, chúng ta sẽ khám phá các tùy chọn có sẵn để đăng ký nó với Laravel để nó có thể thực sự được gọi trong luồng xử lý yêu cầu.

Middleware như  là một cơ chế cho phép bạn tham gia vào luồng xử lý request của một ứng dụng Laravel. Trong một quá trình xử lý route điển hình của Laravel khi thực thi việc xử lý yêu cầu và middleware là một trong những class mà ứng dụng phải thông qua.

Vậy chính xác thì việc xử lý luồng yêu cầu Laravel là gì? Ví dụ: cần xác thực người dùng để quyết định xem họ có được phép truy cập đến route hiện tại hay không.

  • Yêu cầu đăng nhập
  • Chuyển hướng người dùng
  • Thay đổi/chuẩn hoá các tham số
  • Xử lý response được ứng dụng Laravel tạo ra

Thực tế, Laravel mặc định đã có sẵn một số middleware quan trọng. Việc xác thực người dùng cũng được chính middleware này thực thi.

  Cơ cấu xử lý request trong Laravel như thế nào?

Chúng ta sẽ tự tạo ra một middleware tùy biến trong phần này. Như đã nói ở trên, Laravel có sẵn các middleware quan trọng, tuy nhiên để đáp ứng thêm nhu cầu thì chúng ta cần phảo tạo thêm nhiều middleware khác. Nhưng chính xác thì middleware này sẽ làm gì?

Case study cụ thể nhất mà thực tiễn nhất là khi chúng ta truy cập trang web từ bất kỳ thiết bị di động nào, thì sẽ được chuyển hướng đến URL miền phụ tương ứng (vd: m.topdev.vn khi ta vào topdev.vn trên mobile) dành cho mobile với tất cả thông số chuỗi truy vấn còn nguyên vẹn. Tất nhiên bây giờ đã có responsive nhưng đôi khi một phiên bản mobile tinh gọn và tốc độ nhanh sẽ có những tác dụng hay ho khác

Trong middleware tùy chỉnh này, chúng ta sẽ kiểm tra user agent và user được chuyển hướng đến URL tương ứng trên di động nếu họ đang sử dụng thiết bị di động.

Chạy lệnh sau để tạo một template middleware MobileRedirect.

php artisan make:middleware MobileRedirect

Và bạn sẽ tạo ra một file app/Http/Middleware/MobileRedirect.php với code sau.

<?php
  
namespace App\Http\Middleware;
  
use Closure;
  
class MobileRedirect
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

Việc triển khai của method handle dựa trên khung sườn của middleware, và logic chính của middleware mà bạn đang tìm cách triển khai nằm ở đây.

Có 2 loại middleware mà Laravel đang có — before middleware và after middleware.

Before middleware chạy trước khi yêu cầu thực sự được xử lý và phản hồi được tạo ra. Mặt khác, after middleware chạy sau khi yêu cầu được ứng dụng xử lý và phản hồi đã được xây dựng tại thời điểm này.

Trong trường hợp này, chúng ta cần chuyển hướng người dùng trước khi yêu cầu được xử lý và do đó nó sẽ được phát triển như một before middleware.

Tiếp tục chỉnh sửa file app/Http/Middleware/MobileRedirect.php với các nội dung sau.

<?php
  
namespace App\Http\Middleware;
  
use Closure;
  
class MobileRedirect
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // check nếu request từ thiết bị di động
        if ($request->mobile == "1") {
            return redirect('mobile-site-url');
        }
  
        return $next($request);
    }
}

Chúng ta sẽ kiểm tra sự tồn tại của tham số mobile và nếu có giá trị TRUE, người dùng sẽ được chuyển hướng đến URL trên thiết bị di động. Lúc này bạn cần sử dụng một thư viên phát hiện user agent để lấy thông tin user ở client.

Tiếp tục ta sẽ gọi $next($request) giúp yêu cầu được xử lý thêm. Điều quan trọng cần lưu ý trong trường hợp này là chúng ta đã thiết lập logic phát hiện thiết bị di động trước khi gọi $next($request), và nó trở thành before middleware.

Sau đó chúng ta tạo một after middleware để xử lý các yêu cầu trên.

<?php
  
namespace App\Http\Middleware;
  
use Closure;
  
class CustomMiddleWare
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
         
        /* Viết logic code ở đây nha */
         
        return $response;
    }
}

Lúc này, middleware tùy chỉnh của chúng ta gần như đã sẵn sàng để được test thử. Bạn cần phải đăng ký middleware của bạn trong Laravel. Ta mở file app/Http/Kernel.php

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];

Chúng tha thêm middleware tùy chỉnh của mình vào mảng trên sau:

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    \App\Http\Middleware\MobileRedirect::class,
];

Sau khi thêm vào, chúng ta thử truy cập vào bất kỳ route nào của Laravel bằng chuỗi truy vấn mobile=1 và xem kết quả, lúc này coi như chúng ta đã đăng ký thành công middleware do mình tạo. Đôi khi bạn chỉ muốn chạy middleware cho các route xác định hãy sử dụng $routeMiddleware.

Có thể bạn muốn xem thêm:

Golang là gì? 9 Framework tối ưu “cực căng” cho Golang

Quản lý các Laravel route gọn hơn và dễ dàng hơn

Tại sao lại nên dùng integration tests với React, Redux và Router

Việc làm Laravel lương nghìn đô đang chờ anh em apply tại đây.