如何在 REST api 中确定请求的来源

Posted

技术标签:

【中文标题】如何在 REST api 中确定请求的来源【英文标题】:How to determine where a request is coming from in a REST api 【发布时间】:2014-08-26 18:06:57 【问题描述】:

我有一个带有控制器的 RESTful API,当它被我的 android 应用程序点击时,它应该返回一个 JSON 响应,当它被网络浏览器点击时,它应该返回一个“视图”。我什至不确定我是否以正确的方式接近这一点。我正在使用 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', 'Api\Post\PostController@index');

在上述方法中,我将 api 调用和 Web 用户的控制器分开。但是如果你想使用同一个控制器,那么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 是否与给定模式匹配。使用此方法时,您可以使用* 字符作为通配符。

【讨论】:

当您使用 cloudflare 之类的服务时,您的回答非常有用。因为我注意到当使用 ajax 发出 http 请求时,标头会被 cloudflare 更改,并且 Laravel 会根据 Accept 标头中的值确定请求是否需要 json。使用 $request->is('api/*') 而不是 $request->expectsJson() 对我来说就像一个魅力。【参考方案2】:

使用这种方式。您可以简单地将 URL 识别为调用表单(Web 或 API)

控制器代码

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

路线代码

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

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

【讨论】:

【参考方案3】:

你可以使用

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

【讨论】:

恭喜您从 6 岁的已接受答案中复制了两行。【参考方案4】:

你可以像这样使用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 等。


参考 Laravel 的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';

【讨论】:

事情是,从浏览器访问 API 时,我的所有请求都没有使用 ajax。我应该吗? 对,我已经修改了我的答案。您需要通过将请求中的 accept 标头设置为“application/json”来确保您的应用程序请求 json。稍后将更新其内部工作方式。

以上是关于如何在 REST api 中确定请求的来源的主要内容,如果未能解决你的问题,请参考以下文章

调用Azure REST API时如何使用分页

如何在 C# 中使用 Magento 2 API 创建 REST 请求?

如何在React中处理REST API请求

如何保护 Grails 中的所有 REST 请求和响应

如何使用 Scala 在具有请求正文的 REST API 上执行 GET 请求?

Yammer REST API - 如何从不同来源 (CORS) 获取数据?