#php #android #rest #laravel
#php #Android #rest #laravel
Вопрос:
У меня есть RESTful API с контроллерами, которые должны возвращать ответ JSON при попадании в мое приложение для Android и «просмотр» при попадании в веб-браузер. Я даже не уверен, что правильно подхожу к этому. Я использую Laravel, и вот как выглядит мой контроллер
class TablesController extends BaseController {
public function index()
{
$tables = Table::all();
return Response::json($tables);
}
}
Мне нужно что-то вроде этого
class TablesController extends BaseController {
public function index()
{
$tables = Table::all();
if(beingCalledFromWebBrowser){
return View::make('table.index')->with('tables', $tables);
}else{ //Android
return Response::json($tables);
}
}
Видите, чем ответы отличаются друг от друга?
Ответ №1:
Примечание:: Это для будущих зрителей
Подход, который я нашел удобным, используя префикс api
для вызовов api. В файле маршрута используйте
Route::group('prefix'=>'api',function(){
//handle requests by assigning controller methods here for example
Route::get('posts', 'ApiPostPostController@index');
}
В приведенном выше подходе я разделяю контроллеры для вызова api и веб-пользователей. Но если вы хотите использовать тот же контроллер, то Laravel Request
есть удобный способ. Вы можете определить префикс в вашем контроллере.
public function index(Request $request)
{
if( $request->is('api/*')){
//write your logic for api call
$user = $this->getApiUser();
}else{
//write your logic for web call
$user = $this->getWebUser();
}
}
is
Метод позволяет проверить, соответствует ли URI входящего запроса заданному шаблону. Вы можете использовать *
символ в качестве подстановочного знака при использовании этого метода.
Комментарии:
1. Ваш ответ очень полезен, когда вы используете такой сервис, как cloudflare. Потому что я заметил, что при выполнении http-запроса с помощью ajax заголовки изменяются cloudflare, и поскольку Laravel определяет, ожидает ли запрос json, на основе значения в заголовке Accept. Использование $request-> is(‘api /*’) вместо $request-> expectsJson() сработало для меня как по волшебству.
Ответ №2:
Вы можете использовать Request::wantsJson()
вот так:
if (Request::wantsJson()) {
// return JSON-formatted response
} else {
// return HTML response
}
В основном, что Request::wantsJson()
делает, так это проверяет, является ли accept
заголовок в запросе application/json
, и возвращает true или false на основе этого. Это означает, что вам нужно будет убедиться, что ваш клиент также отправляет заголовок «accept: application / json».
Обратите внимание, что мой ответ здесь не определяет, «поступает ли запрос из REST API», а скорее определяет, запрашивает ли клиент ответ в формате JSON. Мой ответ по-прежнему должен быть способом сделать это, хотя, поскольку использование REST API не обязательно означает, что требуется ответ JSON. REST API может возвращать XML, HTML и т.д.
Ссылка на Illuminate Http Request от Laravel Запрос на HTTP-запрос:
/**
* Determine if the current request is asking for JSON in return.
*
* @return bool
*/
public function wantsJson()
{
$acceptable = $this->getAcceptableContentTypes();
return isset($acceptable[0]) amp;amp; $acceptable[0] == 'application/json';
}
Комментарии:
1. дело в том, что я не использую ajax для всех своих запросов при запуске API из браузера. должен ли я?
2. Хорошо, я исправил свой ответ. Вам нужно убедиться, что ваше приложение запрашивает json, установив
accept
заголовок в запросе на «application / json». Через некоторое время будет обновлено, как это работает внутри.
Ответ №3:
Используйте этот способ. вы можете просто определить URL, являющийся формой вызова (Web или API)
Код контроллера
if ( Request::capture()->expectsJson() )
{ return "API Method"; }
else
{ return "Web Method"; }
Код маршрута
Для api.php Route::post(«категория», «CategoryController@index»);
Для Web.php Route::get(«категория», «CategoryController@index»);
Ответ №4:
Вы можете использовать
if ($request->wantsJson()) {
// enter code heree
}
Комментарии:
1. Поздравляю с копированием двух строк из принятого ответа 6-летней давности.
Ответ №5:
Использует ли ваше приложение вообще другие заголовки или токен авторизации? Если это произойдет, вы можете создать вспомогательную функцию для проверки заголовков на наличие ключа. Наше приложение отправляет заголовок авторизации (для passport), в то время как наш веб-интерфейс использует веб-cookie passport в веб-сеансе, поэтому я просто ищу ключ авторизации, чтобы знать, что это приложение:
if(request()->hasHeader('Authorization')){
//is from app
}
Ответ №6:
У меня ничего из этого не сработало, потому что у меня была другая структура маршрута.
Можно было бы сделать это и так.
public function __construct(Request $request) {
$this->request = $request;
$this->isApi = $this->request->segment(1) === 'api' ? true : false;
}
Затем используйте его таким образом в вашем контроллере.
if($this->isApi){
//do things for api view
} else {
//do things for html view
}
Надеюсь, это поможет.
Ответ №7:
You can easily check the route that came from either web or API with this.
if($request->route()->getPrefix() === 'api') {
// Your logic
}