如何为web客户端和本地移动应用程序设计laravel 5.1应用程序


How to design laravel 5.1 application for web client and native mobile apps

我想制作一个适用于web的Laravel 5.1应用程序和适用于移动应用程序的api。我想为api请求返回json,为web浏览器返回view。目前,我设置了不同的路线和不同的控制器。在这种方法中,我重复代码。我不知道设计这个体系结构的最佳方法是什么。此外,我也浏览过一些类似的帖子,建议在网络浏览器中使用angular.js。

// web controller
Route::resource('product', 'ProductController');
// api controller 
Route::group(['prefix' => 'api'], function() {
    Route::resource('product', 'APIProductController');
});

您可以有两种基本方法:

  • 保留单独的路由和控制器,但将所有公共控制器的代码移动到一个服务中。这可能是最干净、最灵活的解决方案,因为它可以很容易地在未来独立更新API和web方法
  • 或者,您可以将api和web请求路由到同一个控制器,将Request对象传递到其中,然后根据某个请求属性决定返回哪个响应,json或html

例如,对于第二种方法,你可以这样做:

// web controller
Route::resource('product', 'ProductController');
// api controller 
Route::group(['prefix' => 'api'], function() {
    Route::resource('product', 'ProductController');
});
// and in the ProductController you have
public function index(Request $request) 
{
    // do some stuff...
    if ($request->segment(1) === 'api') { // route prefix was api
        // return json
    } else {
        // return the view
    }
}

您也可以使用$request->wantsJson((方法检查Accept:头,或者您可以在所有API调用中传递一个特殊的GET变量(例如?_format=json(,以定义响应格式应为json,正如@Bogdan Kuštan已经建议的那样。IMHO如果你已经在url上使用了api前缀,那么只需检查一下就更可靠、更干净了。

一种方法是使用内容协商方法。您将传递头Accept: application/json,然后您的应用程序将返回json格式的响应。然而,有些代理服务器不尊重内容协商,那么你的应用程序就会崩溃(你可以在这里阅读更多Drupal放弃内容协商的原因(。

另一种可能性是使用一些GET变量来返回请求的格式,例如:/api/product?format=json

此外,您可以从/api调用传递变量:

Route::get('/api/product', ['as' => 'product', function(){
    return App::make('ProductController')->index('json');
}]);
public function index($format) {
    // Your controller code
    if ($format == 'json') {
        // return JSON
    }
    // return HTML
}

或者,您可以直接解析URI,看看它是否以/API开头(不推荐(。我的选择是内容协商或/和format GET变量。