Laravel: RESTful API với Laravel


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
 
RESTful APL Laravel

Representation State Transfer (REST) hoặc RESTful web service là một cách cung cấp khả năng tương tác giữa các hệ thống máy tính trên internet. Dịch vụ này cho phép các hệ thống yêu cầu truy cập và thao tác các biểu diễn văn bản của tài nguyên web bằng cách sử dụng một tập hợp thống nhất và được xác định trước của các hoạt động không trạng thái. Cũng trong lập trình máy tính, giao diện lập trình ứng dụng (API) là một tập hợp các định nghĩa, giao thức và công cụ chương trình con để xây dựng các ứng dụng. Một API tốt giúp phát triển chương trình dễ dàng hơn bằng cách cung cấp tất cả các khối xây dựng, sau đó được lập trình viên kết hợp lại với nhau. Do đó, API RESTful là giao diện chương trình ứng dụng sử dụng HTTP yêu cầu NHẬN, PUT, POST và XÓA dữ liệu. Đối với bài viết này, tôi sẽ sử dụng Laravel 5.3 để phát triển dự án RESTful API.

Đối với bài viết này, tôi sẽ xây dựng một ứng dụng blog bằng cách sử dụng Laravel 5.x

Hãy bắt đầu bằng cách tạo một dự án Laravel mới.

Bước 1

Mở terminal hoặc dấu nhắc lệnh của bạn và gõ các lệnh sau. Hãy chắc chắn rằng bạn đã cài đặt trình soạn thảo trên máy của mình.

composer create-project --prefer-dist laravel/laravel my-blog

cd vào thư mục dự án của my my blog blog, mở tệp composer.json và thêm các phụ thuộc sau.

"tymon / jwt-auth": "0,5. *",
"barryvdh / laravel-cors": "^ 0.8.2"

Sau đó chạy

composer update

Bước 2

Trong tệp cấu hình app.php, dưới mảng nhà cung cấp, hãy thêm vào như sau

Tymon \ JWTAuth \ Providers \ JWTAuthServiceProvider :: class,
Barryvdh \ Cors \ ServiceProvider :: class

Sau đó, dưới mảng bí danh, thêm vào như sau

'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,

Trên thiết bị đầu cuối hoặc dấu nhắc lệnh của bạn chạy

php artisan vendor:publish

Thêm vào

"cors" => \Barryvdh\Cors\HandleCors::class,

đến kho giữa tuyến của bạn trong \ App \ http \ Kernel.php

Bước 3

Theo mặc định, Laravel 5.3 đi kèm với các tệp di chuyển bảng người dùng và bảng đặt lại mật khẩu. Mở terminal hoặc dấu nhắc lệnh và chạy lệnh bên dưới

php artisan make:migration create_articles_table

Điều này sẽ tạo một tệp trong thư mục \ cơ sở dữ liệu \ di chuyển \ với dấu thời gian được gắn trước tên tệp, ví dụ: 2016 2016_10_26_155720_create_articles_table.php.

Trong tệp, thêm khối mã sau:

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users');
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('excerpts');
            $table->text('body');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('articles');
    }
}

Chạy lệnh dưới đây trong terminal hoặc dấu nhắc lệnh:

php artisan migrate

Điều này sẽ tạo ra các bảng bên trong cơ sở dữ liệu.

Bước 4

Tạo một bộ điều khiển mới có tên ApiContoder bằng cách chạy lệnh này trên terminal hoặc dấu nhắc lệnh

php artisan make:controller ApiController
<?php
namespace App\Http\Controllers;
use Illuminate\Pagination\LengthAwarePaginator as Paginator;
use Response;
use \Illuminate\Http\Response as Res;
/**
 * Class ApiController
 * @package App\Modules\Api\Lesson\Controllers
 */
class ApiController extends Controller{
    /**
     * Create a new authentication controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->beforeFilter('auth', ['on' => 'post']);
    }
    /**
     * @var int
     */
    protected $statusCode = Res::HTTP_OK;
    /**
     * @return mixed
     */
    public function getStatusCode()
    {
        return $this->statusCode;
    }
    /**
     * @param $message
     * @return json response
     */
    public function setStatusCode($statusCode)
    {
        $this->statusCode = $statusCode;
        return $this;
    }

    public function respondCreated($message, $data=null){
        return $this->respond([
            'status' => 'success',
            'status_code' => Res::HTTP_CREATED,
            'message' => $message,
            'data' => $data
        ]);
    }

    /**
     * @param Paginator $paginate
     * @param $data
     * @return mixed
     */
    protected function respondWithPagination(Paginator $paginate, $data, $message){
        $data = array_merge($data, [
            'paginator' => [
                'total_count'  => $paginate->total(),
                'total_pages' => ceil($paginate->total() / $paginate->perPage()),
                'current_page' => $paginate->currentPage(),
                'limit' => $paginate->perPage(),
            ]
        ]);
        return $this->respond([
            'status' => 'success',
            'status_code' => Res::HTTP_OK,
            'message' => $message,
            'data' => $data
        ]);
    }

    public function respondNotFound($message = 'Not Found!'){
        return $this->respond([
            'status' => 'error',
            'status_code' => Res::HTTP_NOT_FOUND,
            'message' => $message,
        ]);
    }

    public function respondInternalError($message){
        return $this->respond([
            'status' => 'error',
            'status_code' => Res::HTTP_INTERNAL_SERVER_ERROR,
            'message' => $message,
        ]);
    }
    public function respondValidationError($message, $errors){
        return $this->respond([
            'status' => 'error',
            'status_code' => Res::HTTP_UNPROCESSABLE_ENTITY,
            'message' => $message,
            'data' => $errors
        ]);
    }
    public function respond($data, $headers = []){
        return Response::json($data, $this->getStatusCode(), $headers);
    }
    public function respondWithError($message){
        return $this->respond([
            'status' => 'error',
            'status_code' => Res::HTTP_UNAUTHORIZED,
            'message' => $message,
        ]);
    }
}

Controller này mở rộng từ lớp Controller cơ sở, lớp này sẽ được sử dụng để xử lý tất cả các phản hồi yêu cầu API.

Bước 5

Tạo một lớp Transformer trong thư mục App\Repository\Transformers.

<?php namespace App\Repository\Transformers;
abstract class Transformer {
    /*
     * Transforms a collection of lessons
     * @param $lessons
     * @return array
     */
    public function transformCollection(array $items){
        return array_map([$this, 'transform'], $items);
    }
    public abstract function transform($item);
}

Sau đó, cũng tạo một lớp UserTransformer sẽ mở rộng lớp Transfomer.

<?php
namespace App\Repository\Transformers;

class UserTransformer extends Transformer{
    public function transform($user){
        return [
            'fullname' => $user->name,
            'email' => $user->email,
            'api_token' => $user->api_token,
        ];
    }
}

Lớp này trừu tượng hóa dữ liệu đến từ mô hình bằng cách ẩn cấu trúc của cơ sở dữ liệu, do đó không có truy vấn trực tiếp từ API đến mô hình.

Bước 6

Bước tiếp theo là tạo lớp UserContoder mở rộng lớp ApiControll

php artisan make:controller UserController
<?php namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use App\Http\Requests;
use JWTAuth;
use Response;
use App\Repository\Transformers\UserTransformer;
use \Illuminate\Http\Response as Res;
use Validator;
use Tymon\JWTAuth\Exceptions\JWTException;

class UserController extends ApiController
{
    /**
     * @var \App\Repository\Transformers\UserTransformer
     * */
    protected $userTransformer;

    public function __construct(userTransformer $userTransformer)
    {
        $this->userTransformer = $userTransformer;
    }

    /**
     * @description: Api user authenticate method
     * @author: Adelekan David Aderemi
     * @param: email, password
     * @return: Json String response
     */
    public function authenticate(Request $request)
    {
        $rules = array (
            'email' => 'required|email',
            'password' => 'required',
        );
        $validator = Validator::make($request->all(), $rules);
        if ($validator-> fails()){
            return $this->respondValidationError('Fields Validation Failed.', $validator->errors());
        }
        else{
            $user = User::where('email', $request['email'])->first();
            if($user){
                $api_token = $user->api_token;
                if ($api_token == NULL){
                    return $this->_login($request['email'], $request['password']);
                }
                try{
                    $user = JWTAuth::toUser($api_token);
                    return $this->respond([
                        'status' => 'success',
                        'status_code' => $this->getStatusCode(),
                        'message' => 'Already logged in',
                        'user' => $this->userTransformer->transform($user)
                    ]);
                }catch(JWTException $e){
                    $user->api_token = NULL;
                    $user->save();
                    return $this->respondInternalError("Login Unsuccessful. An error occurred while performing an action!");
                }
            }
            else{
                return $this->respondWithError("Invalid Email or Password");
            }
        }
    }

    private function _login($email, $password)
    {
        $credentials = ['email' => $email, 'password' => $password];

        if ( ! $token = JWTAuth::attempt($credentials)) {
            return $this->respondWithError("User does not exist!");
        }
        $user = JWTAuth::toUser($token);
        $user->api_token = $token;
        $user->save();
        return $this->respond([
            'status' => 'success',
            'status_code' => $this->getStatusCode(),
            'message' => 'Login successful!',
            'data' => $this->userTransformer->transform($user)
        ]);
    }

    /**
     * @description: Api user register method
     * @author: Adelekan David Aderemi
     * @param: lastname, firstname, username, email, password
     * @return: Json String response
     */
    public function register(Request $request)
    {
        $rules = array (
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|min:6|confirmed',
            'password_confirmation' => 'required|min:3'
        );
        $validator = Validator::make($request->all(), $rules);
        if ($validator-> fails()){
            return $this->respondValidationError('Fields Validation Failed.', $validator->errors());
        }
        else{
            $user = User::create([
                'name' => $request['name'],
                'email' => $request['email'],
                'password' => \Hash::make($request['password']),
            ]);
            return $this->_login($request['email'], $request['password']);
        }
    }

    /**
     * @description: Api user logout method
     * @author: Dang Tran Long
     * @param: null
     * @return: Json String response
     */
    public function logout($api_token)
    {
        try{
            $user = JWTAuth::toUser($api_token);
            $user->api_token = NULL;
            $user->save();
            JWTAuth::setToken($api_token)->invalidate();
            $this->setStatusCode(Res::HTTP_OK);
            return $this->respond([
                'status' => 'success',
                'status_code' => $this->getStatusCode(),
                'message' => 'Logout successful!',
            ]);

        }catch(JWTException $e){
            return $this->respondInternalError("An error occurred while performing an action!");
        }
    }
}

Bước 7

Sau đó, bên trong tệp tuyến đường api.php thêm sau đó

Route::group(['middleware' => 'cors', 'prefix' => '/v1'], function () {
    Route::post('/login', 'UserController@authenticate');
    Route::post('/register', 'UserController@register');
    Route::get('/logout/{api_token}', 'UserController@logout');
});

Bước 8

Bắt đầu máy chủ phát triển địa phương laravel

php artisan serve

Sử dụng một công cụ kiểm tra API có tên  POSTMAN  để kiểm tra chức năng đăng ký, đăng nhập và đăng xuất. Xem ảnh chụp màn hình bên dưới.

Đăng ký người dùng

 

Đăng nhập người dùng

 

Đăng xuất người dùng

 
» Tiếp: Hướng dẫn Laravel API: Cách xây dựng và kiểm tra một RESTful API
« Trước: groupBy() không làm việc
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!