iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Software Development

跟著官方文件學習Laravel, 並實作出一個會員登入系統系列 第 14

Day14 跟著官方文件學習Laravel-實作API(ㄧ)

昨天介紹了什麼是API及RESTful,今天要API對User進行CRUD,我們就利用laravel提供的方法來實作吧。

php artisan make:controller api/UserController --api

他幫我們建立一個API的Controller,接著我們在Route放上路由

Route::get('/user', [UserController::class, 'index']);
Route::get('/user/{id}', [UserController::class, 'show']);
Route::post('/user', [UserController::class, 'store']);
Route::put('/user/{id}', [UserController::class, 'update']);
Route::delete('/user/{id}', [UserController::class, 'destroy']);

這樣,當我們實作完Controller後,API就建好了。

這個Controller中提供我們不同的方法,這些方法分別對應到HTTP中的幾種Method,而我們用相同的PATH對應到不同的方法,會得到不同的結果,盡量去符合RESTful API規範。

URI description HTTP Method Controller Method
api/user 取得所有User GET index
api/user/{id} 取得該id User GET show
api/user 新增User POST store
api/user/{id} 更新id User PUT/PATCH update
api/user/{id} 刪除id User DELETE destroy

我們就要跟著這些Controller Method去實作
從index開始

public function index()
    {
        return response()->json(User::select('id', 'name', 'account')->get());
    }

回傳所有User資訊,並用response()->json()回傳Json格式。
回傳的資料長這樣

[{"id":1,"name":"test","account":"123"},{"id":2,"name":"nn","account":"456"},{"id":4,"name":"Jim","account":"jim"}]

有點不方便閱讀,可以使用json parser去解析他。

那show呢,就加上where的判斷就可以囉

public function show($id)
    {
        return response()->json(User::select('id', 'name', 'account')->where('id', $id)->first());
    }

第三個method我們要實作store,這跟之前做的signUp有點像,由於部分程式雷同,這邊把它抽出成service使用

public function signUp(
        string $account,
        string $password,
        string $username
        )
    {
        $validator = Validator::make(['password' => $password], [
            'password' => 'regex:' . UserService::PASSWORD_REGEX
        ]);
        if ($validator->fails()) {
            throw new PasswordInvalidException("密碼需要6位數以上,並且至少包含大寫字母、小寫字母、數字、符號各一");
        }
    }

前面一樣是先判斷password是否符合格式,不符合則丟出例外,我們在另外寫一個例外PasswordInvalidException

<?php

namespace App\Exceptions;

class PasswordInvalidException extends \RuntimeException
{

    public function render()
    {
        return response()->json([
            'error' => $this->getMessage(),
        ]);
    }
}

接著我們檢查帳號是否存在,若存在,一樣拋出例外AccountExistException

public function signUp(
        string $account,
        string $password,
        string $username
        )
    {
        $validator = Validator::make(['password' => $password], [
            'password' => 'regex:' . UserService::PASSWORD_REGEX
        ]);
        if ($validator->fails()) {
            throw new PasswordInvalidException();
        }
        $user = User::where('account', $account)->first();
        if($user !== null){
            throw new AccountExistException();
        }
        User::create([
            'account' => $account,
            'password' => Hash::make($password),
            'name' => $username
        ]);
    }
class AccountExistException extends \RuntimeException
{

    public $error = "帳號重複註冊";

    public function render()
    {
        return response()->json([
            'error' => $this->error,
        ]);
    }
}

最後,我們的service長這樣

class UserService
{
    const PASSWORD_REGEX = "/^(?=.*[^a-zA-Z0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{6,}$/";

    public function signUp(
        string $account,
        string $password,
        string $username
        )
    {
        $validator = Validator::make(['password' => $password], [
            'password' => 'regex:' . UserService::PASSWORD_REGEX
        ]);
        if ($validator->fails()) {
            throw new PasswordInvalidException();
        }
        $user = User::where('account', $account)->first();
        if($user !== null){
            throw new AccountExistException();
        }
        User::create([
            'account' => $account,
            'password' => Hash::make($password),
            'name' => $username
        ]);
        return true;
    }

}

這樣不管是我的ap或command都可以使用了,先改寫command看看吧

public function handle(UserService $userService)
    {
        $account = $this->argument('account');
        $password = $this->argument('password');
        $username = $this->argument('username');
        try{
            if($userService->signUp($account, $password, $username)){
                $this->line("註冊成功");
            }
        } catch (Exception $e){
            $this->error($e->getMessage());
        }
        
        return 0;
    }

這邊利用依賴注入獲取$userService,並直接利用signUp幫我們創建帳號

試著創建一個帳號

php artisan sign-up JimChien bbbC1_ Jim

好,確定OK後,這就完成一半啦,那我們下一半在明天繼續吧。


上一篇
Day13 跟著官方文件學習Laravel-了解RESTful API
下一篇
Day15 跟著官方文件學習Laravel-實作API(二)
系列文
跟著官方文件學習Laravel, 並實作出一個會員登入系統30

尚未有邦友留言

立即登入留言