简体   繁体   中英

How to determine where a request is coming from in a REST api

I have an RESTful API with controllers that should return a JSON response when is being hit by my android application and a "view" when it's being hit by a web browser. I'm not even sure I'm approaching this the right way. I'm using Laravel and this is what my controller looks like

class TablesController extends BaseController {

    public function index()
    {
        $tables  = Table::all();

        return Response::json($tables);
    }
}

I need something like this

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);
        }
    }

See how the responses differ from each other?

Note::This is for future viewers

The approach I found convenient using a prefix api for api calls. In the route file use

Route::group('prefix'=>'api',function(){
    //handle requests by assigning controller methods here for example
    Route::get('posts', 'Api\Post\PostController@index');
}

In the above approach, I separate controllers for api call and web users. But if you want to use the same controller then Laravel Request has a convenient way. You can identify the prefix within your controller.

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();
    }
}

The is method allows you to verify that the incoming request URI matches a given pattern. You may use the * character as a wildcard when utilizing this method.

You can use Request::wantsJson() like this:

if (Request::wantsJson()) {
    // return JSON-formatted response
} else {
    // return HTML response
}

Basically what Request::wantsJson() does is that it checks whether the accept header in the request is application/json and return true or false based on that. That means you'll need to make sure your client sends an "accept: application/json" header too.

Note that my answer here does not determine whether "a request is coming from a REST API", but rather detects if the client requests for a JSON response. My answer should still be the way to do it though, because using REST API does not necessary means requiring JSON response. REST API may return XML, HTML, etc.


Reference to Laravel's Illuminate\Http\Request :

/**
 * 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';
}

Use this Way. you can simply identify URL being call form ( Web or API )

Controller code

if ( Request::capture()->expectsJson()  )
     {  return "API Method";  }
     else
     {  return "Web Method";     }

Route Code

For api.php Route::post("category","CategoryController@index");

For Web.php Route::get("category","CategoryController@index");

You can use

if ($request->wantsJson()) {
     // enter code heree
}

Does your app use different headers or authorization token at all? If it does, you can make a helper function to check the headers for a key. Our app sends Authorization header (for passport) while our web end uses the passport web cookie in the web session, so I just lookout for the Authorization key to know it is app:

if(request()->hasHeader('Authorization')){
//is from app
}

None of this worked for me because I had a different route structure.

One could do it like this too.

public function __construct(Request $request) {
    $this->request = $request;
    $this->isApi = $this->request->segment(1) === 'api' ? true : false;
}

Then in use it like this in your controller.

if($this->isApi){
  //do things for api view
} else {
 //do things for html view
}

Hope it helps.

You can easily check the route that came from either web or API with this.

if($request->route()->getPrefix() === 'api') {
   // Your logic
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM