Xây Dựng RESTful API Với Laravel

Xây Dựng RESTful API Với Laravel

Ở phần trước chúng ta đã cùng nhau Thao Tác Với Migrations Và Seeding Trên Laravel. Ở phần tiếp theo này chúng ta sẽ cùng nhau tìm hiểu RESTful API với dữ liệu đã tạo ở bài trước nhé.

Việc xây dựng 1 API với sự hỗ trợ của Laravel Framework khá là dễ dàng. Nên trong bài viết này ngoài việc xây dựng API mình sẽ kết hợp việc Module hóa một project để sau này mở rộng project 1 cách dễ dàng.

API là cái gì?

API viết tắt của Application Programming Interface là một tập các quy tắc và cơ chế mà theo đó, một ứng dụng hay một thành phần sẽ tương tác với một ứng dụng hay thành phần khác.
API có thể trả về dữ liệu mà bạn cần cho ứng dụng của mình ở những kiểu dữ liệu phổ biến như XML, JSON, YAML hoặc bất kỳ định dạng nào tùy thuộc vào yêu cầu.
REST viết tắt của REpresentational State Transfer là một dạng chuyển đổi cấu trúc dữ liệu, một kiểu kiến trúc để viết API.
Nó sử dụng phương thức HTTP đơn giản để tạo cho giao tiếp giữa các máy. Vì vậy, thay vì sử dụng một URL cho việc xử lý một số thông tin người dùng, REST gửi một yêu cầu HTTP như GET, POST, DELETE, vv đến một URL để xử lý dữ liệu.
Như vậy RESTful API là một tiêu chuẩn dùng trong việc thiết kế các API cho các ứng dụng web để quản lý các resource. RESTful là một trong những kiểu thiết kế API được sử dụng phổ biến ngày nay để cho các ứng dụng (web, mobile…) khác nhau giao tiếp với nhau.

Kiến trúc REST bắt nguồn từ việc thiết kế sao cho phù hợp với giao thức HTTP thông dụng nhất.
Các phương thức HTTP method có các định dạng sau:

Status code là gì?

Khi chúng ta request một API nào đó thường thì sẽ có vài status code để nhận biết sau:

  • 200 OK – Trả về thành công cho những phương thức GET, PUT, PATCH hoặc DELETE.
  • 201 Created – Trả về khi một Resouce vừa được tạo thành công.
  • 204 No Content – Trả về khi Resource xoá thành công.
  • 304 Not Modified – Client có thể sử dụng dữ liệu cache.
  • 400 Bad Request – Request không hợp lệ
  • 401 Unauthorized – Request cần có auth.
  • 403 Forbidden – bị từ chối không cho phép.
  • 404 Not Found – Không tìm thấy resource từ URI
  • 405 Method Not Allowed – Phương thức không cho phép với user hiện tại.
  • 410 Gone – Resource không còn tồn tại, Version cũ đã không còn hỗ trợ.
  • 415 Unsupported Media Type – Không hỗ trợ kiểu Resource này.
  • 422 Unprocessable Entity – Dữ liệu không được xác thực
  • 429 Too Many Requests – Request bị từ chối do bị giới hạn

Vậy là đã sơ qua lý thuyết,trước khi vào bắt tay vào xây dựng các bạn nên cài postman là một công cụ để test API nhé.

Module hóa dự án (HMVC)

Việc đầu tiên cần làm là chúng ta sẽ module hóa project nhé.

Laravel đã được thiết kế rất tốt theo mô hình MVC (Model - View - Controller) cho các dự án trung bình và nhỏ. Đối với các sự án lớn hoặc cần mở rộng, được nhiều người phát triển thì mô hình MVC bộc lộ một vài khuyết điểm, đáng kể nhất là khó quản lý code khi số lượng file trong model/view/controller tăng trưởng không ngừng.

Laravel đã cung cấp cho chúng ta khả năng module hoá sử dụng mô hình HMVC (Hierarchy - Model - View - Controller) để mỗi nhóm tính năng trỡ thành 1 module có cấu trúc MVC và routing riêng biệt nhằm thuận tiện cho việc quản lý.

Để thực hiện module hóa ở trong thư mục app các bạn tạo 1 thư mục Modules.

Sau khi tạo folder xong chúng ta sẽ khao báo folder này trong mục autoload/psr-4 ở file composer.json

"autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/",
            "Modules\\": "app/Modules/"
        }
},

Trong folder app/Modules, chúng ta sẽ tạo 1 service provider trong file ModuleServiceProvider.php.

app/Modules/ModuleServiceProvider.php sẽ có nội dung:

<?php

namespace App\Modules;
use File;


class ModuleServiceProvider extends \Illuminate\Support\ServiceProvider{
  public function boot(){
    $modules = array_map('basename', \File::directories(__DIR__));
    foreach ($modules as $module) {
      if(file_exists(__DIR__.'/'.$module.'/routes.php')) {
          include __DIR__.'/'.$module.'/routes.php';
      }

      $view_path = __DIR__.'/'.$module.'/Views';
      if(is_dir($view_path)) {
         $this->loadViewsFrom($view_path, $module);
      }
    }

  }
  public function register() {}

}

Khai báo service provider này trong config/app.php tại mục providers:

'providers' => [
    ...
    /*
     * Custom Service Providers...
     */
    App\Modules\ModuleServiceProvider::class,
]

Tiến hành tạo các module

Tạo một module tên là Api thì chúng ta cần có cấu trúc sau:

app/
└── Modules
    ├── Api
    │   ├── Controllers
    │   │   └── Products.php
    │   └── routes.php
    └── ModuleServiceProvider.php

Vì trong module Api chúng ta không sử dụng views nên ko cần phải thêm vào, model ta cũng dùng chung nên cũng không cần thiết.
Tiếp theo ở bên trong file app/Modules/Api/routes.php

<?php
$namespace = 'App\Modules\Api\Controllers';
Route::group([
    'module' => 'Api',
    'prefix'=>'api/v1',
    'namespace' => $namespace
], function () {
    // Lấy danh sách sản phẩm
    Route::get('products', '[email protected]')->name('products.index');

    // Lấy thông tin sản phẩm theo id
    Route::get('product/{id}', '[email protected]')->name('product.show');

    // Thêm sản phẩm mới
    Route::post('product', '[email protected]')->name('product.store');

    // Cập nhật thông tin sản phẩm theo id
    # Sử dụng put nếu cập nhật toàn bộ các trường
    Route::put('product/{id}', '[email protected]')->name('product.update');

    // Xóa sản phẩm theo id
    Route::delete('product/{id}', '[email protected]')->name('product.destroy');

});

Chúng ta mở file products.php để xử lý trả về tất cả danh sách sản phẩm bên trong hàm index nhé:

<?php
namespace App\Modules\Api\Controllers;

use App\Http\Controllers\Controller;
use App\Product;
use Request;
class Products extends Controller
{
    public function index(){
        return Product::all(); // hàm all sẽ lất ra tất cả sản phẩm
    }
}

Kết quả thu được khi chúng ta test trên postman với url http://laravel.local/api/v1/products (trả về danh sách sản phẩm) như sau:



Tiếp đến vấn là phương thức GET nhưng lấy theo ID của sản phẩm,bên trong products.php có thêm hàm sau:

public function show($id)
{
        return Product::findOrFail($id);
}

Kết quả thu được khi chúng ta test trên postman với url http://laravel.local/api/v1/product/1 (trả về sản phẩm với id là 1) như sau:



Tiếp đến vấn là phương thức POST để tạo sản phẩm mới, bên trong products.php có thêm hàm sau:

public function store(Request $request)
{
    return Product::create($request->all());
}

Kết quả thu được khi chúng ta test trên postman với url http://laravel.local/api/v1/product bằng phương thức POST như sau:



Tiếp đến là phương thức PUT để update sản phẩm, bên trong products.php có thêm hàm sau:

public function update($id,Request $request)
{
    return Product::where('id',$id)->update($request->all());
}

Kết quả thu được khi chúng ta test trên postman với url http://laravel.local/api/v1/product/1 (update sản phẩm với id là 1) bằng phương thức PUT như sau:



Cuối cùng là phương thức DELETE để xóa sản phẩm, bên trong products.php có thêm hàm sau:

public function destroy($id)
{
    return Product::where('id',$id)->delete();
}

Kết quả thu được khi chúng ta test trên postman với url http://laravel.local/api/v1/product/1 (xóa sản phẩm với id là 1) bằng phương thức DELETE như sau:


Tạm kết

Như vậy là chúng ta đã hoàn thành xây dựng một API theo chuẩn RESTful API, cũng thông qua bài này các bạn cũng biết cách đăng ký 1 service providermodule hóa trong một project như thế nào rồi đấy. Hãy đón chờ bài kế tiếp của mình nhé, chúc các bạn thành công.