Laravel+API 接口

Laravel+API 接口

网课连接:BIlibili.

中文文档.

1.RestFul Api编码风格

一、API设计

  1. 修改hosts,C:\Windows\System32\drivers\etc\hosts,增加127.0.0.1 api.lv8.com # Laravel 框架 用这个域名来测试(推荐规范)

  2. 在命令行中使用 php artisan serve --host api.lv8.com

  3. .envconfig/database.php中配置mysql数据库等服务用的wamp;

    注意这里的 database.php需要配置 prefix属性

    php 复制代码
            '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'),
                ]) : [],
            ],
  4. 安装Postman,测试接口,https://cdn.liyanhui.com/data.json

二、RestFul

  1. RestFul Api 是一种设计风格,推荐的一种规范,有助于统一协同和管理;

  2. 这里提供两个网址

    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-Controller

    php 复制代码
    use App\Http\Controllers\UserController;
    
    Route::apiResourcce('users', UserController::class);
  • 检查一下路由是否有效

    php artisan route:list

现在是可以请求 www.lv8.com:8000/api/users

4.生成标准API

专门创建一个API抽象类,并继承调用它。

生成标准API

  1. 创建一个抽象类 BaseController 实现一个生成API的方法,让控制器继承;

    php artisan make:controller BaseController

    php 复制代码
    /**
     * 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);
        }
    }
  2. UserController 中继承上面的抽象类

    php 复制代码
    class UserController extends BaseController
    {
        public function index()
        {
            return $this->create([1,2,3], '数据获取成功',200);  // 当前类是 BaseController 的子类,create是继承后的方法
    }

    继承后直接使用 $this 来调用抽象类的方法

5.数据列表和分页

数据列表返回

  1. 创建一个 Model/User ,用于数据库模型处理,用命令生成;

    php artisan make:model api/User

    php 复制代码
    // 空模型即可
    class User extends Model
    {
        use HasFactory;
    }
  2. 注意配置数据库连接,账号、密码、数据库名、前缀等

  3. 使用模型方式调用数据库链接,并返回数据

    php 复制代码
    // 在 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 复制代码
<?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

    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修改一下

php 复制代码
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;

添加数据函数

php 复制代码
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'
php 复制代码
// 用户名(必填+唯一+长度限制)
'username' => 'required|unique:users|min:2|max:10',

// 密码(必填+最小长度+确认)
'password' => 'required|min:6|confirmed'

// 邮箱(必填+格式验证)
'email' => 'required|email'

快捷记忆口诀

  • 必填非空required

  • 数据类型stringnumericinteger

  • 长度控制min/max/size

  • 唯一性unique(数据库校验)

  • 格式验证emailurldate

  • 二次确认confirmed(如密码确认)

许可赋值 App\Models\api;

php 复制代码
<?php

namespace 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动词既可
php 复制代码
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.

php 复制代码
<?php

namespace 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,用例

html 复制代码
<!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>
相关推荐
BingoGo2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
BingoGo5 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·laravel
JaguarJack5 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理6 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
QQ5110082856 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php