PhalApi 如何請求接口服務

如何請求接口服務
HTTP協議下的請求方式
對於PhalApi,默認是通過HTTP協議進行通信的。根據接口服務的具體實現,可以使用GET或POST方式請求。

訪問入口
如前面所言,PhalApi推薦將系統對外可訪問的根目錄設置爲/path/to/phalapi/public。PhalApi的統一訪問入口文件是/path/to/phalapi/public/index.php文件。

當配置的域名爲:dev.phalapi.net,並且已將根目錄設置到public,此時訪問的URL是:

http://dev.phalapi.net

當未配置域名,亦未配置根目錄時,此時訪問的URL是(顯然更長更不優雅):

http://localhost/phalapi/public/index.php

如果尚未安裝,請先閱讀下載與安裝。

如何指定待請求的接口服務?
默認情況下,可以通過s參數指定待請求的接口服務,當s未傳時,缺省使用默認接口服務,即:App.Site.Index。以下三種方式是等效的,都是請求默認接口服務。

未傳s參數
?s=Site.Index,省略命名空間,默認使用App
?s=App.Site.Index,帶有命名空間前綴
也就是說,當請求除默認接口服務以外的接口服務時,其格式可以二選一:

?s=Class.Action
或者:?s=Namespace.Class.Action
其中,Namespace表示命名空間前綴,Class爲接口服務類名,Action爲接口服務方法名,這三者通常首字母大寫,並使用英文點號分割。最終執行的類方法是:Namespace/Api/Class::Action()。需要注意的是:

溫馨提示:s參數爲service參數的縮寫,即使用?s=Class.Action等效於?service=Class.Action,兩者都存在時優先使用service參數。

關於Namespace命名空間
Namespace是指命名空間中/Api/的前半部分。並且需要在根目錄下的composer.json文件中進行autoload的註冊,以便能正常自動加載類文件。如默認已經註冊的App命名空間:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/app"
        }
    }
}

當命名空間存在子命名空間時,在請求時使用下劃線分割。反過來,當不存在多級命名空間時,命名空間不應該含有下劃線。

關於Class接口服務類名
Class接口服務類名是指命名空間中/Api/的後半部分,並且必須是PhalApi/Api的子類。當命名空間存在子命名空間時,在請求時同樣改用下劃線分割。類似的,當不存在多級命名空間時,命名空間不應該含有下劃線。

關於Action接口服務方法名
待請求的Action,應該是public訪問級別的類方法,並且不能是PhalApi/Api已經存在的方法。

一些示例
以下是一些綜合的示例。

PhalApi 2.x 請求的s參數    對應的文件    執行的類方法
無    ./src/app/Api/Site.php    App\Api\Site::Index()
?s=Site.Index    ./src/app/Api/Site.php    App\Api\Site::index()
?s=Weibo.Login    ./src/app/Api/Weibo.php    App\Api\Weibo::login()
?s=User.Weibo.Login    ./src/user/Api/Weibo.php    User\Api\Weibo::login()
?s=Company_User.Third_Weibo.Login    ./src/company_user/Api/Third/Weibo.php    Company\User\Api\Third\Weibo::login()
上面示例中假設,已經在composer.json中配置有:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/app",
            "User\\": "src/user",
            "Company\\User\\": "src/company_user"
        }
    }
}

開啓URI路由匹配
注意!本功能需要PhalApi 2.7.0 及以上版本方可支持。

任何情況下,PhalApi都會優先通過service參數,其次是s參數(也就是service的短參數)來定位當前客戶端請求的是哪一個接口服務。

當客戶端未提供service參數,亦未提供s參數時,可以通過開啓sys.enable_uri_match嘗試進行URI路由匹配。

先通過幾個例子來了解開啓URI路由匹配後的訪問效果,以下效果是等效的。

# 通過service指定
http://dev.phalapi.net/?service=App.Usre.Login

# 開啓URI路由匹配後
http://dev.phalapi.net/App/User/Login

# 省略App默認命名空間
http://dev.phalapi.net?s=App.Usre.Login

# 開啓URI路由匹配後
http://dev.phalapi.net/User/Login


原理很簡單,當未提供service參數和s參數時,並且是開啓sys.enable_uri_match後,客戶端可以通過/Namespace/Class/Action這樣的URI訪問接口服務。

除了要在./config/sys.php修改enable_uri_match配置爲true外,還需要同步進行Rewrite規則配置,以便讓你的服務在未找到文件時把請求轉發給index.php處理。參考以下Nginx配置:

server {
    listen 80;
    server_name dev.phalapi.net;
    root /path/to/phalapi/public;
    charset utf-8;

    # 開啓URI路由匹配
    location / {
        try_files $uri $uri/ $uri/index.php;
    }
    if (!-e $request_filename) {
        rewrite ^/(.*)$ /index.php last;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    access_log logs/dev.phalapi.net.access.log;
    error_log logs/dev.phalapi.net.error.log;
}


路由如何匹配?
開啓路由匹配,並且正確配置Nginx或Apache的Rewrite規則後,客戶端可以通過以下方式訪問接口服務:

常見的路徑:/Namespace/Class/Action
常見的路徑,且帶有GET參數:/Namespace/Class/Action?xx=123
常見的路徑,且前面包含index.php文件:/index.php/Namespace/Class/Action
常見的路徑,且同時包含index.php文件和GET參數:/public/index.php/Namespace/Class/Action?xx=123
類似地,如果Namespace是App,那麼可以忽略不寫,即有:

默認App,常見的路徑:/Class/Action
默認App,常見的路徑,且帶有GET參數:/Class/Action?xx=123
默認App,常見的路徑,且前面包含index.php文件:/index.php/Class/Action
默認App,常見的路徑,且同時包含index.php文件和GET參數:/public/index.php/Class/Action?xx=123
下面是針對登錄接口的例子:

// 常見的路徑
http://dev.phalapi.net/App/User/Login

// 常見的路徑,且帶有GET參數
http://dev.phalapi.net/App/User/Login?username=dogstar&password=123456

// 常見的路徑,且前面包含index.php文件
http://dev.phalapi.net/index.php/App/User/Login

// 常見的路徑,且同時包含index.php文件和GET參數(入口文件必須是index.php,前面目錄路徑可自定義)
http://dev.phalapi.net/public/index.php/App/User/Login?username=dogstar&password=123456

擴展:如何定製接口服務的傳遞方式?
雖然我們約定統一使用?s=Namespace.Class.Action的格式來傳遞接口服務名稱,但如果項目有需要,也可以採用其他方式來傳遞。例如類似於Yii框架的請求格式:?r=Namespace/Class/Action。

如果需要定製傳遞接口服務名稱的方式,可以重寫PhalApi\Request::getService()方法。以下是針對改用斜槓分割,並換用r參數名字的實現代碼片段。

// 文件 ./src/app/Common/Request.php

<?php
namespace App\Common;

class Request extends \PhalApi\Request {

    public function getService() {
        // 優先返回自定義格式的接口服務名稱
        $service = $this->get('r');
        if (!empty($service)) {
            $namespace = count(explode('/', $service)) == 2 ? 'App.' : '';
            return $namespace . str_replace('/', '.', $service);
        }

        return parent::getService();
    }
}

實現好自定義的請求類後,需要在項目的DI配置文件./config/di.php進行註冊。在最後的加上一行:

$di->request = new App\Common\Request();

這時,便可以通過新的方式來進行接口服務的請求的了。即:

原來的方式    現在的方式
?s=Site.Index    ?r=Site/Index
?s=App.Site.Index    ?r=App/Site/Index
?s=Hello.World    ?r=Hello/World
?s=App.Hello.World    ?r=App/Hello/World
這裏有幾個注意事項:

1、重寫後的方法需要轉換爲原始的接口服務格式,即:Namespace.Class.Action,注意別遺漏命名空間。
2、爲保持兼容性,在取不到自定義的接口服務名稱參數時,應該返回parent::getService()。
如果想再進行URL路由的美化,可以結合重定向配置來使用。

例如Nginx參考配置:

if (!-e $request_filename) {
    rewrite ^/(.*)$ /index.php?r=$1 last;
}

例如Apache參考配置:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/?r=$1 [QSA,PT,L]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
</IfModule>

又如IIS參考配置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php/?r={R:1}" appendQueryString="true" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

最終效果會類似,當訪問:http://api.phalapi.net/user/login,就會變成:http://api.phalapi.net/?r=user/login,然後觸發上在的擴展規則,最終等效於:http://api.phalapi.net/?s=user.login
 

發佈了204 篇原創文章 · 獲贊 28 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章