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後,这就完成一半啦,那我们下一半在明天继续吧。


<<:  Day 15 AWS云端实作起手式第五弹 建立流量负载分流Elastic Load Balancer (ELB)

>>:  [Day-28] R语言 - 分群应用(五) 分群预测 - 提升模型准确度 ( Improve Model Accuracy by Clustering in R.Studio )

[C 语言笔记--Day11] Makefile 的粗略笔记

Makefile 是一个是一个常常用来编译 C/C++ 专案的工具, 对应到 JAVA 了话,就有点...

如何使用WYSIWYG Python GUI 设计工具快速设计出子视窗及产出程序码呢?

Python GUI中如果只有一个主视窗那将会很不好用,那该如何快速设计出不同的子视窗呢? 网路上有...

AZ-304 Practice Exam - The key to Transform Failure into Success

Azure Solutions Architect Expert AZ-304 certificat...

Day 16:axios 先封装,API 轻松发

上篇我们在单一元件内使用 axios 发送 API,但如果专案规模愈来愈大,需要同时管理多个功能的 ...

Day 28 - 建立自己的K线资料库 (下)

本篇重点 建立Index,加快SQLite存取速率 产生日K线资料 产生周K线资料 产生月K线资料 ...