如何用Laravel 5.1开发返回JSON响应的多端平台REST API
嘿,我刚好在Laravel 5.1上搭建过只返回JSON的API服务,适配Web和移动端前端,给你梳理几个核心步骤,照着做就能搞定:
1. 路由分组与隔离
Laravel 5.1还没有专门的api.php路由文件,所以建议把所有API路由统一放在routes.php的分组里,加上前缀和专属中间件,方便管理:
Route::group(['prefix' => 'api', 'middleware' => 'api'], function () { // 你的API路由,比如: Route::get('/users/{id}', 'UserController@show'); Route::post('/users', 'UserController@store'); // 其他CRUD路由... });
这里的api中间件组默认包含了throttle(限流)和bindings,你可以在app/Http/Kernel.php里调整它的成员。
2. 控制器只返回JSON响应
所有API控制器的方法都不要调用view(),直接用response()->json()返回数据,或者甚至直接返回数组/模型实例——Laravel会自动帮你转换成JSON响应:
<?php namespace App\Http\Controllers; use App\User; use Illuminate\Http\Request; class UserController extends Controller { public function show($id) { $user = User::findOrFail($id); // 直接返回模型,Laravel自动转JSON return $user; // 或者自定义响应结构: // return response()->json(['data' => $user], 200); } public function store(Request $request) { $user = User::create($request->all()); return response()->json(['data' => $user], 201); // 201表示创建成功 } }
3. 统一错误处理(替换Blade错误页)
默认情况下Laravel抛出异常会返回HTML错误页,这对移动端不友好。你需要修改app/Exceptions/Handler.php的render方法,让API请求返回JSON格式的错误:
public function render($request, Exception $e) { // 判断是否是API请求:通过路由前缀或者请求头 if ($request->is('api/*') || $request->wantsJson()) { $statusCode = method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500; return response()->json([ 'error' => [ 'message' => $e->getMessage(), 'code' => $statusCode ] ], $statusCode); } // 非API请求还是用默认的错误处理 return parent::render($request, $e); }
4. 处理请求验证的JSON错误
当你用自定义请求类做验证时,默认的验证失败会返回重定向,需要改成JSON响应。在你的请求类里重写failedValidation方法:
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Http\Exceptions\HttpResponseException; use Illuminate\Contracts\Validation\Validator; class StoreUserRequest extends FormRequest { public function rules() { return [ 'name' => 'required|string', 'email' => 'required|email|unique:users', ]; } protected function failedValidation(Validator $validator) { throw new HttpResponseException( response()->json(['errors' => $validator->errors()], 422) ); } }
5. 优化模型返回(隐藏敏感字段)
为了避免返回密码、token等敏感数据,在模型里设置$hidden属性:
class User extends Model { protected $hidden = ['password', 'remember_token']; }
6. 跨域支持(可选)
如果你的Web前端和移动端来自不同域名,需要处理CORS问题。可以自定义一个CORS中间件:
<?php namespace App\Http\Middleware; use Closure; class Cors { public function handle($request, Closure $next) { return $next($request) ->header('Access-Control-Allow-Origin', '*') // 生产环境建议指定具体域名 ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') ->header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); } }
然后在app/Http/Kernel.php里注册这个中间件,并加到API路由组的中间件里:
protected $routeMiddleware = [ // 其他中间件... 'cors' => \App\Http\Middleware\Cors::class, ];
修改路由分组:
Route::group(['prefix' => 'api', 'middleware' => ['api', 'cors']], function () { // ... });
按照这些步骤配置后,你的Laravel 5.1后端就完全是一个纯JSON API服务了,不用碰Blade模板,完美适配Web和移动端前端的调用需求。
内容的提问来源于stack exchange,提问作者MaToXz

