昨天介紹了什麼是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後,這就完成一半啦,那我們下一半在明天繼續吧。