francolot
Tengo una API RESTful con controladores que deberían devolver una respuesta JSON cuando mi aplicación de Android la golpea y una “vista” cuando la golpea un navegador web. Ni siquiera estoy seguro de estar abordando esto de la manera correcta. Estoy usando Laravel y así es como se ve mi controlador
class TablesController extends BaseController {
public function index()
{
$tables = Table::all();
return Response::json($tables);
}
}
necesito algo como esto
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);
}
}
¿Ves cómo las respuestas difieren entre sí?
Shafi
Nota::Esto es para futuros espectadores
El enfoque que encontré conveniente usando un prefijo api
para llamadas api. En el uso del archivo de ruta
Route::group('prefix'=>'api',function(){
//handle requests by assigning controller methods here for example
Route::get('posts', 'Api\Post\PostController@index');
}
En el enfoque anterior, separo los controladores para llamadas api y usuarios web. Pero si quieres usar el mismo controlador entonces Laravel Request
tiene una forma conveniente. Puede identificar el prefijo dentro de su controlador.
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();
}
}
Él is
El método le permite verificar que el URI de la solicitud entrante coincida con un patrón dado. Puedes usar el *
carácter como comodín al utilizar este método.
-
Su respuesta es muy útil cuando usa un servicio como cloudflare. Porque noté que al hacer una solicitud http con ajax, cloudflare cambia los encabezados y, dado que Laravel determina si una solicitud espera json en función del valor en el encabezado Aceptar. Usar $request->is(‘api/*’) en lugar de $request->expectsJson() funcionó de maravilla para mí.
– El más estúpido
7 de noviembre de 2021 a las 14:04
Unnawut
Puedes usar Request::wantsJson()
Me gusta esto:
if (Request::wantsJson()) {
// return JSON-formatted response
} else {
// return HTML response
}
Básicamente lo que Request::wantsJson()
lo que hace es comprobar si el accept
el encabezado de la solicitud es application/json
y devolver verdadero o falso en función de eso. Eso significa que deberá asegurarse de que su cliente también envíe un encabezado “aceptar: aplicación/json”.
Tenga en cuenta que mi respuesta aquí no determina si “una solicitud proviene de una API REST”, sino que detecta si el cliente solicita una respuesta JSON. Sin embargo, mi respuesta debería ser la forma de hacerlo, porque el uso de la API REST no significa necesariamente que se requiera una respuesta JSON. La API REST puede devolver XML, HTML, etc.
Referencia a Laravel Iluminar\Http\Solicitar:
/**
* Determine if the current request is asking for JSON in return.
*
* @return bool
*/
public function wantsJson()
{
$acceptable = $this->getAcceptableContentTypes();
return isset($acceptable[0]) && $acceptable[0] == 'application/json';
}
-
La cosa es que no uso ajax para todas mis solicitudes cuando presiono la API desde el navegador. ¿debería?
– Frankelot
5 de julio de 2014 a las 21:20
-
Bien, he modificado mi respuesta. Deberá asegurarse de que su aplicación solicite json configurando
accept
encabezado en la solicitud de “aplicación/json”. Se actualizará en un momento de cómo funciona internamente.– Unnawut
5 de julio de 2014 a las 21:26
Usa este Camino. simplemente puede identificar la URL como formulario de llamada (Web o API)
Código del controlador
if ( Request::capture()->expectsJson() )
{ return "API Method"; }
else
{ return "Web Method"; }
Código de ruta
Para api.php Route::post(“category”,”CategoryController@index”);
Para Web.php Route::get(“category”,”CategoryController@index”);
Puedes usar
if ($request->wantsJson()) {
// enter code heree
}
¿Su aplicación utiliza encabezados o tokens de autorización diferentes? Si es así, puede crear una función de ayuda para verificar los encabezados en busca de una clave. Nuestra aplicación envía un encabezado de Autorización (para el pasaporte) mientras que nuestro extremo web usa la cookie web del pasaporte en la sesión web, así que solo busco la clave de Autorización para saber que es la aplicación:
if(request()->hasHeader('Authorization')){
//is from app
}
Sprepar
Nada de esto funcionó para mí porque tenía una estructura de ruta diferente.
Uno podría hacerlo así también.
public function __construct(Request $request) {
$this->request = $request;
$this->isApi = $this->request->segment(1) === 'api' ? true : false;
}
Luego, utilícelo así en su controlador.
if($this->isApi){
//do things for api view
} else {
//do things for html view
}
Espero eso ayude.
Imrán
You can easily check the route that came from either web or API with this.
if($request->route()->getPrefix() === 'api') {
// Your logic
}