Laravel+API 接口
網課連接:BIlibili.
中文文檔.
1.RestFul Api編碼風格
一、API設計
-
修改hosts,
C:\Windows\System32\drivers\etc\hosts
,增加127.0.0.1 api.lv8.com # Laravel 框架
用這個域名來測試(推薦規范) -
在命令行中使用
php artisan serve --host api.lv8.com
-
在
.env
和config/database.php
中配置mysql數據庫等服務用的wamp;注意這里的
database.php
需要配置 prefix屬性'mysql' => ['driver' => 'mysql','url' => env('DATABASE_URL'),'host' => env('DB_HOST', '127.0.0.1'),'port' => env('DB_PORT', '3306'),'database' => env('DB_DATABASE', 'forge'),'username' => env('DB_USERNAME', 'forge'),'password' => env('DB_PASSWORD', ''),'unix_socket' => env('DB_SOCKET', ''),'charset' => 'utf8mb4','collation' => 'utf8mb4_unicode_ci','prefix' => 'laravel_', # 重點'prefix_indexes' => true,'strict' => true,'engine' => null,'options' => extension_loaded('pdo_mysql') ? array_filter([PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),]) : [],],
-
安裝Postman,測試接口,
https://cdn.liyanhui.com/data.json
二、RestFul
-
RestFul Api
是一種設計風格,推薦的一種規范,有助于統一協同和管理; -
這里提供兩個網址
RESTful API
RESTful API 設計指南
狀態碼使用規范
2.資源控制器和路由
一、資源控制器
- 創建一個API-Controller
php artisan make:controller UserController --api
二、資源路由
-
創建好 API 資源控制器之后,在
route/web.php
配置相關api資源路由;Route::apiResourcce('users', 'UserController');
HTTP類型 | 路由URI | 控制器方法 | 路由命名 | 描述 |
---|---|---|---|---|
GET | users | index() | users.index | 獲取數據列表 |
POST | users | store() | users.store | 創建頁的接受處理 |
GET | users/{user} | show() | users.show | 獲得一條數據 |
PUT/PATCH | users/{user} | update() | users.update | 從編輯頁中接受處理 |
DELETE | users/{user} | destroy() | users.destroy | 刪除一條數據 |
PS:可以通過
php artisan route:list
來查看資源路由列表
3.安裝Laravel8.x
-
使用
composer
創建composer create-project --prefer-dist laravel/laravel blog
-
提前配置好 hosts 文件,然后運行下面命令
php artisan serve --host www.lv8.com
-
創建一個API-Controller
php artisan make:controller UserController --api
在UserController 中的 index 寫個
return 'index';
. -
然后再
routes/api.php
中引入API-Controlleruse App\Http\Controllers\UserController;Route::apiResourcce('users', UserController::class);
-
檢查一下路由是否有效
php artisan route:list
現在是可以請求
www.lv8.com:8000/api/users
4.生成標準API
專門創建一個API抽象類,并繼承調用它。
生成標準API
-
創建一個抽象類
BaseController
實現一個生成API的方法,讓控制器繼承;php artisan make:controller BaseController
/*** Class BaseController* @package App\Http\Controllers* api 基類*/ abstract class BaseController extends Controller {// 生成api方法protected function create($data, $msg = '', $code = 200){// 返回api結果$result = [// 狀態碼'code' => $code,//自定義信息'msg' => $msg,// 數據返回'data' => $data];return response($result, $code);} }
-
在
UserController
中繼承上面的抽象類class UserController extends BaseController {public function index(){return $this->create([1,2,3], '數據獲取成功',200); // 當前類是 BaseController 的子類,create是繼承后的方法 }
繼承后直接使用
$this
來調用抽象類的方法
5.數據列表和分頁
數據列表返回
-
創建一個
Model/User
,用于數據庫模型處理,用命令生成;php artisan make:model api/User
// 空模型即可 class User extends Model {use HasFactory; }
-
注意配置數據庫連接,賬號、密碼、數據庫名、前綴等
-
使用模型方式調用數據庫鏈接,并返回數據
// 在 UserController 中 use App\Models\api\User;public function index() {$reslut = User::select('id', 'username', 'email')->get(); // 這里只要了三個字段return $this->create($reslut, '數據獲取成功',200);// 使用 paginate 來進行分頁 // return $this->create(User::select('id', 'username', 'email')->paginate(5), '數據獲取成功',200); // 這里是前五條數據 // return $this->create(User::select('id', 'username', 'email')->simplePaginate(5), '數據獲取成功',200); // 簡潔版 }
注意:這里就已經連接數據庫了。
分頁操作:沒有太多需求的話,一般使用簡單形式
simplePaginate
.測試接口:
http://www.lv8.com:8000/api/users?page=2
6.配置404錯誤
首先規范一下錯誤狀態的狀態碼,具體說明如下:
- 200(OK)-表示已在響應中發出
- 204(無內容) - 資源有空表示,請求成功,但無數據
- 301(Moved Permanently) - 資源的URI已被更新
- 303 (See Other) -其他(如,負載均衡)
- 304 (not modified) -資源未更改(緩存)
- 400 (bad request)- 指代壞請求(如,參數錯誤)
- 404 (not found)- 資源不存在(找不到頁面)
- 406 (not acceptable)- 服務端不支持所需表示
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務端當前無法處理請求
框架已經非常智能的提供了404的處理,只要固定路徑配置 404 錯誤頁即可;
覆蓋掉系統自帶的404:resources/views/errors/404.blade.php
<?php
/** API格式* path:resources/views/errors/404.blade.php* */
// 設置 HTTP 狀態碼為 404
http_response_code(404);// 設置響應頭為 JSON 格式
header('Content-Type: application/json');$result = [// 狀態碼'code' => 404,// 自定義信息'msg' => '資源不存在~',// 數據返回, 返回一個空'data' => []
];echo json_encode($result); // 必須要加 json_encode 格式轉換
7.單數據處理及錯誤
-
資源控制器中 show,表示獲取單一數據,傳遞id參數即可
-
那么,我們在show 方法里構造獲取方式,具體如下:
位置:
UserController.php
public function show($id) {// 判斷id 合法if(!is_numeric($id)){return $this->create([], 'id參數錯誤!!!', 400);}// 獲取數據$result = User::select('id', 'username', 'email')->find($id); // 通過id查找// 判斷是否為空if(empty($result)){return $this->create([], '請求成功,但無數據~', 204);} else {return $this->create($result, '數據獲取成功~', 200);} }
PS:路由地址為:
http://www.lv8.com:8000/api/users/20
注意,需要把 BaseController
中的 return
修改一下
class BaseController extends Controller
{// 生成api方法protected function create($data, $msg = '', $code = 200){// 返回api結果$result = [// 狀態碼'code' => $code,// 自定義信息'msg' => $msg,// 數據返回'data' => $data];return response($result);}
}
8.新增數據API處理
- 新增一條數據,首先要進行驗證,這里找事服務器端的,用驗證器即可
- 使用Postman來模擬新增時,選擇Body中的form-data(表單),并用POST;
添加數據函數
public function store(Request $request) // post 進入
{// 獲取提交數據$data = $request->all();// 數據驗證,required 不可為空, unique 唯一,$validator = Validator::make($data, ['username' => 'required|unique:users|min:2|max:10', // 2 < length < 10'password' => 'required|min:6', // x > 6]);// 驗證并提示if ($validator->fails()) { // fails 如果發生錯誤
// return $this->create([], "提交的數據有誤~", 400);return $this->create([], $validator->errors(), 400); // $validator->errors() 是框架自帶的錯誤提示英文} else {// 寫入數據$addData = User::create($data);// 存在,說明成功了if ($addData) {return $this->create($data, '數據添加成功~', 200);}}return $data;// 數據驗證
// $validator
}
數據驗證
規則 | 說明 | 示例 |
---|---|---|
required | 字段必填(非空) | 'email' => 'required' |
nullable | 允許字段為 null | 'phone' => 'nullable' |
string | 必須是字符串類型 | 'name' => 'string' |
min:value | 最小長度/值(字符串、數組、數值) | 'password' => 'min:6' |
max:value | 最大長度/值 | 'username' => 'max:20' |
email | 驗證郵箱格式 | 'email' => 'email' |
unique:table | 數據庫唯一性校驗 | 'username' => 'unique:users' |
exists:table | 值必須存在于數據庫 | 'role' => 'exists:roles,name' |
confirmed | 與 字段名_confirmation 匹配 | 'password' => 'confirmed' |
in:value1,value2 | 值必須在指定列表內 | 'status' => 'in:active,pending' |
numeric | 必須是數字 | 'age' => 'numeric' |
date | 驗證日期格式(如 Y-m-d ) | 'birthday' => 'date' |
// 用戶名(必填+唯一+長度限制)
'username' => 'required|unique:users|min:2|max:10',// 密碼(必填+最小長度+確認)
'password' => 'required|min:6|confirmed'// 郵箱(必填+格式驗證)
'email' => 'required|email'
? 快捷記憶口訣
-
必填非空:
required
-
數據類型:
string
、numeric
、integer
-
長度控制:
min
/max
/size
-
唯一性:
unique
(數據庫校驗) -
格式驗證:
email
、url
、date
-
二次確認:
confirmed
(如密碼確認)
許可賦值 App\Models\api;
<?phpnamespace App\Models\api;use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;class User extends Model
{use HasFactory;// 許可賦值protected $fillable = ['username', 'password','email', 'details'];
}
9.刪除數據API處理
刪除API DELETE
- API刪除,使用DELETE動詞既可
public function destroy($id)
{// 判斷id 合法if(!is_numeric($id)){return $this->create([], 'id參數錯誤!!!', 400);}// 查找數據,并刪除 find$users = User::find($id);// 刪除的數據不存在if(empty($users)){return $this->create([], '數據不存在~', 400);}// 執行刪除返回if($users->delete()){return $this->create([], '數據刪除成功~', 200);}return $this->create([], '請求成功,刪除失敗~', 200);
}
使用DELETE
方式,請求地址:http://www.lv8.com:8000/api/users/20
Controller
.
<?phpnamespace App\Http\Controllers;use App\Models\api\client;
use Illuminate\Http\Request;class ClientController extends BaseController
{/*** Display a listing of the resource.** @return \Illuminate\Http\Response*/public function index(){// 獲取全部數據$data = client::select('id', 'email', 'password_hash', 'phone_number', 'first_name', 'last_name')->get();return $this->create($data, 'success', 200);}/*** Store a newly created resource in storage.** @param \Illuminate\Http\Request $request* @return \Illuminate\Http\Response*/public function store(Request $request){// 驗證請求數據$validatedData = $request->validate(['email' => 'required|email|unique:clients','password_hash' => 'required','phone_number' => 'required','first_name' => 'required','last_name' => 'required']);// 創建新的客戶端記錄$client = client::create($validatedData);return $this->create($client, 'Client created successfully', 201);}/*** Display the specified resource.** @param int $id* @return \Illuminate\Http\Response*/public function show($id){// 單數據處理// 判斷id是否合法if(!is_numeric($id)){return $this->create([], 'id參數錯誤~', 400);}// 獲取數據$reslut = client::select('id', 'email', 'password_hash', 'phone_number', 'first_name', 'last_name')->find($id);// 判斷是否為空if(empty($reslut)){return $this->create([], '請求成功但無數據~', 200);}return $this->create($reslut, 'success', 200);}/*** Update the specified resource in storage.** @param \Illuminate\Http\Request $request* @param int $id* @return \Illuminate\Http\Response*/public function update(Request $request, $id){// 判斷id是否合法if(!is_numeric($id)){return $this->create([], 'id參數錯誤~', 400);}// 查找要更新的客戶端記錄$client = client::find($id);if (!$client) {return $this->create([], 'Client not found', 404);}// 驗證請求數據$validatedData = $request->validate(['email' => 'email|unique:clients,email,'.$id,'password_hash' => 'sometimes','phone_number' => 'sometimes','first_name' => 'sometimes','last_name' => 'sometimes']);// 更新客戶端記錄$client->update($validatedData);return $this->create($client, 'Client updated successfully', 200);}/*** Remove the specified resource from storage.** @param int $id* @return \Illuminate\Http\Response*/public function destroy($id){// 判斷id是否合法if(!is_numeric($id)){return $this->create([], 'id參數錯誤~', 400);}// 查找要刪除的客戶端記錄$client = client::find($id);if (!$client) {return $this->create([], 'Client not found', 404);}// 刪除客戶端記錄$client->delete();return $this->create([], 'Client deleted successfully', 200);}
}
axios
,用例
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><style type="text/css">* {padding: 0;margin: 0;}table {font-size: 18px;border-collapse: collapse;width: 700px;height: 80px;margin: 0 auto;text-align: center;}th {width: 100px;height: 68px;padding: 8px 12px;background: yellowgreen;}table,th,td {border: 1px solid yellowgreen;}</style>
</head>
<body><h1>表格</h1><table class="table"><tr><th>id</th><th>username</th><th>gender</th><th>email</th><th>price</th></tr></table><script type="text/javascript">const table = document.querySelector(".table>tbody");let data_str = table.innerHTML;axios({method: 'get',url: 'https://cdn.liyanhui.com/data.json',// data: {}}).then((res) => {// data = res.data;res.data.forEach((value) =>{data_str += `<tr><td>${value.id}</td><td>${value.username}</td><td>${value.gender}</td><td>${value.email}</td><td>${value.price}</td></tr>`;})table.innerHTML = data_str;});</script>
</body>
</html>