手摸手教你让Laravel开发Api更得心应手
2021-01-22 05:11
标签:pac 错误信息 info 信息 完整 短信 常驻内存 isp access https://www.guaosi.com/2019/02/26/laravel-api-initialization-preparation/ 随着前后端完全分离, 内容划水过长,请谨慎打开 当然,你也可以点击这里,直接跳到成果~ 为了模拟AJAX请求,请将 在项目的 1) 在 3) 因为有关于User的命名空间发生了改变,所以我们全局搜索 因为是专门做API的,所以我们要把是API的控制器都放到 使用命令行创建控制器 编写 这里写了index函数,用来下面建立路由后的测试,查看是否可以正常访问。 在 因为我们Api控制器的命名空间是 同时,添加一个 打开 则成功 在创建用户之前,我们先创建验证器,来让我们服务器接收到的数据更安全.当然,我们也要把关于Api验证的放在一个专门的文件夹内。 因为验证器默认的权限验证是 所以我们修改 这样这个命名空间下的验证器都会默认通过权限验证。当然,如果你需要权限验证,可以通过直接覆盖方法。 接着我们开始创建关于 编辑 现在我们来编写创建用户接口,制作一些虚拟数据。(就不使用seeder来填充了) 然后我们创建路由,编辑 打开 最后返回结果是 则成功。 如果返回 则证明验证失败。 然后验证是否可以正常登录。因为我们认证的字段是 打开 则成功 为了测试使用,请自行通过接口创建10个用户。 给出整体控制器信息 给出整体路由信息 以上所有返回的结果,无论正确或者错误,都没有一个统一格式规范,对开发 所有问题,跨域先行。跨域问题没有解决,一切处理都是纸老虎。这里我们使用medz做的cors扩展包 打开 这样跨域请求时,才能返回 打开 打开 接口主流返回 在 1. 起因
PHP
也基本告别了view
模板嵌套开发,转而专门写资源接口。Laravel
是PHP框架中最优雅的框架,国内也越来越多人告别ThinkPHP
选择了Laravel
。Laravel
框架本身对API
有支持,但是感觉再工作中还是需要再做一些处理。Lumen
用起来不顺手,有些包不能很好地支持。所以,将Laravel
框架进行一些配置处理,让其在开发API
时更得心应手。
2. 准备工作
2.1. 环境
1
2
3
PHP > 7.1
MySQL > 5.5
Redis > 2.82.2. 工具
1
2
postman
composer2.3. 使用postman
header头
设置X-Requested-With
为 XMLHttpRequest
2.4. 安装Laravel
Laravel
只要>=5.5
皆可,这里采用文章编写时最新的5.7
版本
1
composer create-project laravel/laravel Laravel --prefer-dist "5.7.*"
2.5. 创建数据库
1
2
3
4
5
6
7
8
9
CREATE TABLE `users` (
`id` INT UNSIGNED NOT NULL PRIMARY KEY auto_increment COMMENT ‘主键ID‘,
`name` VARCHAR ( 12 ) NOT NULL COMMENT ‘用户名称‘,
`password` VARCHAR ( 80 ) NOT NULL COMMENT ‘密码‘,
`last_token` text COMMENT ‘登陆时的token‘,
`status` TINYINT NOT NULL DEFAULT 0 COMMENT ‘用户状态 -1代表已删除 0代表正常 1代表冻结‘,
`created_at` TIMESTAMP NULL DEFAULT NULL COMMENT ‘创建时间‘,
`updated_at` TIMESTAMP NULL DEFAULT NULL COMMENT ‘修改时间‘
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;3. 初始化数据
3.1. Model移动
app
目录下可以看到,有一个User.php
的模型文件。因为Laravel
默认把模型文件放在app
目录下,如果数据表多的话,这里模型文件就会很多,不便于管理,所以我们先要将模型文件移动到其他文件夹内。app
目录下新建Models
文件夹,然后将User.php
文件移动进来。
2) 修改User.php
的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace App\Models; //这里从App改成了App\Models
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $table = ‘users‘;
//去掉我创建的数据表没有的字段
protected $fillable = [
‘name‘, ‘password‘
];
//去掉我创建的数据表没有的字段
protected $hidden = [
‘password‘
];
//将密码进行加密
public function setPasswordAttribute($value)
{
$this->attributes[‘password‘] = bcrypt($value);
}
}App\User
,将其替换为App\Models\User
.我一共搜索到3个文件
1
2
3
4
app/Http/Controllers/Auth 目录下的 RegisterController.php
config 目录下的 services.php
config 目录下的 auth.php
database/factories 目录下的 UserFactory.php3.2. 控制器
app\Http\Controllers\Api
目录下。
1
php artisan make:controller Api/UserController
app/Http/Controllers/Api
目录下的UserController.php
文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
//
public function index(){
return ‘guaosi‘;
}
}3.3. 路由
routes
目录下的api.php
是专门用来写Api接口的路由,所以我们打开它,填写以下内容,做一个测试.
1
2
3
4
5
6
use Illuminate\Http\Request;
Route::namespace(‘Api‘)->prefix(‘v1‘)->group(function () {
Route::get(‘/users‘,‘UserController@index‘)->name(‘users.index‘);
});
App\Http\Controllers\Api
,而Laravel
默认只会在命名空间App\Http\Controllers
下查找控制器,所以需要我们给出namespace
。
prefix
是为了版本号,方便后期接口升级区分。postman
,用get
方式请求你的域名/api/v1/users
,最后返回结果是
1
guaosi
3.4. 创建验证器
先创建一个Request
的基类
1
php artisan make:request Api/FormRequest
false
,导致返回都是403
的权限不通过错误。这里我们没有用到权限认证,为了方便处理,我们默认将权限都是通过的状态。所以,每个文件都需要我们将false
改成true
。
1
2
3
4
5
6
public function authorize()
{
//false代表权限验证不通过,返回403错误
//true代表权限认证通过
return true;
}app/Http/Requests/Api
目录下的 FormRequest.php
文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace App\Http\Requests\Api;
use Illuminate\Foundation\Http\FormRequest as BaseFormRequest;
class FormRequest extends BaseFormRequest
{
public function authorize()
{
//false代表权限验证不通过,返回403错误
//true代表权限认证通过
return true;
}
}UserController
的专属验证器
1
php artisan make:request Api/UserRequest
app/Http/Requests/Api
目录下的 UserRequest.php
文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
namespace App\Http\Requests\Api;
class UserRequest extends FormRequest
{
public function rules()
{
switch ($this->method()) {
case ‘GET‘:
{
return [
‘id‘ => [‘required,exists:shop_user,id‘]
];
}
case ‘POST‘:
{
return [
‘name‘ => [‘required‘, ‘max:12‘, ‘unique:users,name‘],
‘password‘ => [‘required‘, ‘max:16‘, ‘min:6‘]
];
}
case ‘PUT‘:
case ‘PATCH‘:
case ‘DELETE‘:
default:
{
return [
];
}
}
}
public function messages()
{
return [
‘id.required‘=>‘用户ID必须填写‘,
‘id.exists‘=>‘用户不存在‘,
‘name.unique‘ => ‘用户名已经存在‘,
‘name.required‘ => ‘用户名不能为空‘,
‘name.max‘ => ‘用户名最大长度为12个字符‘,
‘password.required‘ => ‘密码不能为空‘,
‘password.max‘ => ‘密码长度不能超过16个字符‘,
‘password.min‘ => ‘密码长度不能小于6个字符‘
];
}
}3.5. 创建用户
打开UserController.php
1
2
3
4
5
6
7
8
9
10
11
12
//用户注册
public function store(UserRequest $request){
User::create($request->all());
return ‘用户注册成功。。。‘;
//用户登录
public function login(Request $request){
$res=Auth::guard(‘web‘)->attempt([‘name‘=>$request->name,‘password‘=>$request->password]);
if($res){
return ‘用户登录成功...‘;
}
return ‘用户登录失败‘;
}api.php
1
2
Route::post(‘/users‘,‘UserController@store‘)->name(‘users.store‘);
Route::post(‘/login‘,‘UserController@login‘)->name(‘users.login‘);postman
,用post
方式请求你的域名/api/v1/users
,在form-data
记得填写要创建的用户名和密码。
1
用户创建成功。。。
1
2
3
4
5
6
7
8
9
10
11
{
"message": "The given data was invalid.",
"errors": {
"name": [
"用户名不能为空"
],
"password": [
"密码不能为空"
]
}
}name
跟password
,而Laravel
默认认证的是email
跟password
。所以我们还要打开app/Http/Controllers/auth
目录下的 LoginController.php
,加入如下代码
1
2
3
4
public function username()
{
return ‘name‘;
}postman
,用post
方式请求你的域名/api/v1/login
最后返回结果是
1
用户登录成功...
3.6. 创建10个用户
3.7. 编写相关资源接口
UserController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
namespace App\Http\Controllers\Api;
use App\Http\Requests\Api\UserRequest;
use App\Models\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class UserController extends Controller
{
//返回用户列表
public function index(){
//3个用户为一页
$users = User::paginate(3);
return $users;
}
//返回单一用户信息
public function show(User $user){
return $user;
}
//用户注册
public function store(UserRequest $request){
User::create($request->all());
return ‘用户注册成功。。。‘;
}
//用户登录
public function login(Request $request){
$res=Auth::guard(‘web‘)->attempt([‘name‘=>$request->name,‘password‘=>$request->password]);
if($res){
return ‘用户登录成功...‘;
}
return ‘用户登录失败‘;
}
}3.8. 编写路由
api.php
1
2
3
4
5
6
7
8
9
use Illuminate\Http\Request;
Route::namespace(‘Api‘)->prefix(‘v1‘)->group(function () {
Route::get(‘/users‘,‘UserController@index‘)->name(‘users.index‘);
Route::get(‘/users/{user}‘,‘UserController@show‘)->name(‘users.show‘);
Route::post(‘/users‘,‘UserController@store‘)->name(‘users.store‘);
Route::post(‘/login‘,‘UserController@login‘)->name(‘users.login‘);
});4. 存在问题
Api
不太友好的,需要我们进行一些修改,让Laravel框架可以更加友好地编写Api。5. 构造
5.1. 跨域问题
5.1.1. 安装medz/cors
1
composer require medz/cors
5.1.2. 发布配置文件
1
php artisan vendor:publish --provider="Medz\Cors\Laravel\Providers\LaravelServiceProvider" --force
5.1.3. 修改配置文件
config/cors.php
,在expose-headers
添加值Authorization
1
2
3
4
5
return [
......
‘expose-headers‘ => [‘Authorization‘],
......
];
header
头为Authorization
的内容,否则在刷新用户token
时不会返回刷新后的token
5.1.4. 增加中间件别名
app/Http/Kernel.php
,增加一行
1
2
3
4
protected $routeMiddleware = [
...... //前面的中间件
‘cors‘=> \Medz\Cors\Laravel\Middleware\ShouldGroup::class,
];5.1.5. 修改路由
routes/api.php
,在路由组中增加使用中间件
1
2
3
4
5
6
Route::namespace(‘Api‘)->prefix(‘v1‘)->middleware(‘cors‘)->group(function () {
Route::get(‘/users‘,‘UserController@index‘)->name(‘users.index‘);
Route::get(‘/users/{user}‘,‘UserController@show‘)->name(‘users.show‘);
Route::post(‘/users‘,‘UserController@store‘)->name(‘users.store‘);
Route::post(‘/login‘,‘UserController@login‘)->name(‘users.login‘);
});5.2. 统一Response响应处理
json
格式,其中包含http状态码
,status请求状态
,data请求资源结果
等等。需要我们有一个API接口全局都能有统一的格式和对应的数据处理。参考于这里。5.2.1. 封装返回的统一消息
app/Api/Helpers
目录(不存在目录自己新建)下新建 ApiResponse.php
填入如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
namespace App\Api\Helpers;
use Symfony\Component\HttpFoundation\Response as FoundationResponse;
use Response;
trait ApiResponse
{
/**
* @var int
*/
protected $statusCode = FoundationResponse::HTTP_OK;
/**
* @return mixed
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* @param $statusCode
* @return $this
*/
public function setStatusCode($statusCode,$httpCode=null)
{
$httpCode = $httpCode ?? $statusCode;
$this->statusCode = $statusCode;
return $this;
}
/**
* @param $data
* @param array $header
* @return mixed
*/
public function respond($data, $header = [])
{
return Response::json($data,$this->getStatusCode(),$header);
}
/**
* @param $status
* @param array $data
* @param null $code
* @return mixed
*/
public function status($status, array $data, $code = null){
if ($code){
$this->setStatusCode($code);
}
$status = [
‘status‘ => $status,
‘code‘ => $this->statusCode
];
$data = array_merge($status,$data);
return $this->respond($data);
}
/**
* @param $message
* @param int $code
* @param string $status
* @return mixed
*/
/*
* 格式
* data:
* code:422
* message:xxx
* status:‘error‘
*/
public function failed($message, $code = FoundationResponse::HTTP_BAD_REQUEST,$status = ‘error‘){
return $this->setStatusCode($code)->message($message,$status);
}
/**
* @param $message
* @param string $status
* @return mixed
*/
public function message($message, $status = "success"){
return $this->status($status,[
‘message‘ => $message
]);
}
/**
* @param string $message
* @return
文章标题:手摸手教你让Laravel开发Api更得心应手
文章链接:http://soscw.com/index.php/essay/45292.html