我想设置正确的路线和型号,所以当我访问www.myapp.com/search?keyword=test时,我会看到数据视图,当我访问api.myapp.com/search?keyword=test时获得完全相同的搜索结果的JSON表示。
如果我像这样整理子域路由:
Route::group(array('domain' => '{subdomain}.myapp.com'), function()
{
Route::get('/', function($subdomain)
{
dd($subdomain);
});
});
使用相同模型方法的最简单方法是什么,而不是使用模型对象数组返回视图(对于非子域路由),如下所示:
return view('search', compact('models'));
我返回一个JSON对象数组,就像这样:
return $models;
注意:子域名不是必需的,也可以是myapp.com/api/search?keyword=test
感谢。
答案 0 :(得分:0)
有几种方法可以做到这一点。
一种选择是根本不使用单独的子域或路径。而是使用内置机制来检查请求的Content-Type
标头中的Accept
。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SearchController extends Controller
{
public function getSearch(Request $req)
{
$keyword = $req->input('keyword');
$results = yourCodeThatDoesTheSearch();
// If the request has header `Accept: */json`, return JSON
if ($req->wantsJson())
{
return $results;
}
// Otherwise, return view
return view('search', compact('results'));
}
}
但是,您可能仍希望使用子域,因为您无法控制请求标头,或者您希望能够轻松指示您将获得哪些响应。
这是使用子域执行此操作的最简单方法:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SearchController extends Controller
{
public function getSearch(Request $req)
{
$keyword = $req->input('keyword');
$results = yourCodeThatDoesTheSearch();
// If the request came to the API subdomain, return JSON
if ($req->route('subdomain') === 'api')
{
return $results;
}
// Otherwise, return view
return view('search', compact('results'));
}
}
但是,如果您打算在代码中的许多地方执行此操作,则应避免在任何地方重复使用相同的if
语句。
相反,创建一个辅助函数:
<?php
use Illuminate\Contracts\Routing\ResponseFactory;
if (! function_exists('response_auto')) {
function response_auto($view, $data, $request, $status = 200, array $headers = [])
{
$factory = app(ResponseFactory::class);
if ($request->wantsJson())
{
return $factory->json($data, $status, $headers);
}
return $factory->view($view, compact('data'), $status, $headers);
}
}
然后您可以在控制器中使用它,如下所示:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SearchController extends Controller
{
public function getSearch(Request $req)
{
$keyword = $req->input('keyword');
$results = yourCodeThatDoesTheSearch();
return response_auto('search', $results, $req);
}
}
答案 1 :(得分:0)
添加到Moshe Katz的答案。如果您只是在控制器中执行$req->wantsJson()
,则可以正常工作。但是,在某些情况下,如果用户点击后退按钮,json将由于缓存而在视图中返回。一个健壮的api将在它自己的控制器中,并使用存储库进行数据库查询。这可能有点矫枉过正。
另一种选择是在您的网址中使用查询参数。
实施例: 在您的ajax客户端(axios)
axios.get('/stuff', {params: {json: true}).then(response => return response);
这将向
发送请求/stuff?json=true
laravel控制器中的(StuffController @ index)
public function index(Request $request)
{
$stuff = Stuff::all();
if ($request->query('json')) {
return $stuff;
}
return view('stuff.index', compact('stuff'));
}
这使您可以轻松识别请求是否需要json,防止因浏览器缓存而导致的不必要的返回,并将代码保存在同一个控制器中。