筋斗雲接口編程 / 創建Web接口項目

[任務]

用筋斗雲框架創建一個Web接口項目叫mysvc,創建數據庫,提供對ApiLog對象的操作接口。

先從github上下載開源的筋斗雲後端框架及示例應用:https://github.com/skyshore2001/jdcloud-php

建議安裝git工具直接下載,便於以後更新,例如直接創建Web接口項目叫mysvc:

git clone https://github.com/skyshore2001/jdcloud-php.git mysvc

如果github訪問困難,也可以用這個git倉庫: http://dacatec.com/git/jdcloud-php.git

配置好Web服務器,php環境和MySQL數據庫。
注意PHP最低版本需要5.4版本,需要打開mysql, pdo, gd等支持。

在Web服務器上將項目下的接口主目錄(即server目錄)暴露出來,假設URL是:

http://localhost/mysvc/

先別急着訪問這個地址,而是先配置數據庫連接等,在瀏覽器中打開這個頁面:

http://localhost/mysvc/tool/init.php

這個工具會先檢查運行環境是否正確,如有異常(比如php版本不對,缺少組件等)請先解決。
然後創建接口應用使用的數據庫和配置文件。

初始化工具運行完後,生成的配置文件爲php/conf.user.php,之後也可以手工編輯該文件。

數據模型定義在主設計文檔DESIGN.wiki中,作爲示例,裏面定義了一些數據模型,像用戶(User),訂單(Ordr)以及前面提過的操作日誌(ApiLog)等,還定義了一些常用接口,如登錄操作(login)等。
我們通過通過命令行工具tool/upgrade.php可以創建或更新數據庫:

cd tool
php upgrade.php
(這時進入upgrade交互操作,輸入initdb命令創建或更新數據庫)
> initdb
(輸入命令q退出)
> q

我們進入server目錄看看:

  • api.php就是接口應用程序,提供Web接口。
  • tool目錄中是一些線上工具,比如查看日誌、計劃任務等。
  • 對象型接口一般寫在文件php/api_objects.php中,函數型接口一般寫在php/api_functions.php中。
    裏面已經包含了一些示例接口,一般在示例基礎上修改即可。
  • 共用邏輯寫在app.php中,各種工具和接口應用程序均可用;注意如果只是多個接口共用的邏輯,直接寫在api.php文件中就可以。

爲了學習對象型接口,我們將php/api_objects.php清空,從頭開始來寫,以暴露ApiLog對象爲例,在php/api_objects.php中加上一句:

class AC_ApiLog extends AccessControl
{
}

這一句代碼就提供了對ApiLog對象的標準增刪改查(CRUD)接口如下:

查詢對象列表,支持分頁、查詢條件、統計等:
ApiLog.query() -> table(id, tm, addr)

添加對象,通過POST參數傳遞字段值,返回新對象的id
ApiLog.add()(tm, addr) -> id

獲取對象
ApiLog.get(id) -> {id, tm, addr}

更新對象,通過POST參數傳遞字段值。
ApiLog.set(id)(tm?, addr?)

刪除對象
ApiLog.del(id)

[接口原型的描述方式]

在上面的接口原型描述中,用了兩個括號的比如add/set操作,表示第一個括號中的參數通過GET參數(也叫URL參數)傳遞,第二個括號中的參數用POST參數(也叫FORM參數)傳遞。
多數接口參數支持用GET方式或POST方式傳遞,除非在接口說明中特別指定。
帶”?”表示參數或返回的屬性是可選項,可以不存在。

接口原型中只描述調用成功時返回數據的數據結構,完整的返回格式是[0, 返回數據];而在調用失敗時,統一返回[非0錯誤碼, 錯誤信息]

我們可以直接用curl工具來模擬前端調用,用add接口添加一行數據,使用HTTP POST請求:

curl http://localhost/mysvc/api.php/ApiLog.add -d "tm=2016-9-9 10:10" -d "addr=shanghai"

curl用”-d”參數指定參數通過HTTP body來傳遞,由於默認使用HTTP POST謂詞和form格式(Content-Type=application/x-www-form-urlencoded),
這種參數一般稱爲POST參數或FORM參數,與通過URL傳遞的GET參數相區別。
結果輸出一個JSON數組:

[0,11338]

0表示調用成功,後面是成功時返回的數據,add操作返回對象id,可供get/set/del操作使用。

用get接口取出這個對象出來看看:

curl http://localhost/mysvc/api.php/ApiLog.get?id=11338

輸出:

[0,{"id":11338,"tm":"2016-09-09 00:00:00","addr":"shanghai"}]

這裏參數id是通過URL傳遞的。
前面說過,未顯式說明時,接口的參數可以通過URL或POST參數方式來傳遞,所以本例中URL參數id也可以通過POST參數來傳遞:

curl http://localhost/mysvc/api.php/ApiLog.get -d "id=11338"

如果取一個不存在的對象,會得到錯誤碼和錯誤信息,比如:

curl http://localhost/mysvc/api.php/ApiLog.get?id=999999

輸出:

[1,"參數不正確"]

再用set接口做一個更新,按接口要求,要將id參數放在URL中,要更新的字段及值用POST參數:

curl http://localhost/mysvc/api.php/ApiLog.set?id=11338 -d "addr=beijing"

輸出:

[0, "OK"]

再看很靈活的query接口,取下列表,默認支持分頁,會輸出一個nextkey字段:

curl http://localhost/mysvc/api.php/ApiLog.query

返回示例:

[0,{
    "h":["id","tm","addr"],
    "d":[[11353,"2016-01-04 18:31:06","::1"],[11352,"2016-02-04 18:30:43","::1"],...],
    "nextkey":11349
}]

返回的格式稱爲壓縮表,”h”爲表頭字段,”d”爲表的數據,在接口描述中用table(id, 其它字段...)表示。

默認返回的JSON數據未經美化,效率較高,如果想看的清楚些,可以在配置文件conf.user.php中設置測試模式:

putenv("P_TEST_MODE=1");

測試模式不僅美化輸出數據,還可返回更多調試信息,前端可用URL參數_debug設置調試等級0-9,如果設置爲9,甚至可以查看SQL調用日誌:

curl http://localhost/mysvc/api.php/ApiLog.query?_debug=9

這在調試SQL語句時很有用。此外,測試模式還會開放某些內部接口,以及缺省允許跨域訪問,便於通過web頁面測試接口。注意線上生產環境絕不可設置爲測試模式。

query接口也支持常用的數組返回,需要加上_fmt=list參數:

curl http://localhost/mysvc/api.php/ApiLog.query -d "_fmt=list"

返回示例:

[0,{
    "list": [
        { "id": 11353, "tm": "2016-01-04 18:31:06", "addr": "::1" },
        { "id": 11352, "tm": "2016-02-04 18:30:43", "addr": "::1" }, 
        ...
    ],
    "nextkey":11349
}]

還可以將_fmt參數指定爲”csv”, “excel”, “txt”等,在瀏覽器訪問時可直接下載相應格式的文件,讀者可自己嘗試。

取下一頁可以用_pagekey字段,還可指定一次取的數據條數,用_pagesz字段:

curl "http://localhost/mysvc/api.php/ApiLog.query?_pagekey=11349&_pagesz=5"

不僅支持分頁,query接口非常靈活,可以指定返回字段、查詢條件、排序方式,
比如查詢2016年1月份的數據(cond參數),結果只需返回id, addr字段(res參數,也可用於get接口),按id倒序排列(orderby參數):

curl http://localhost/mysvc/api.php/ApiLog.query -d "res=id,addr" -d "cond=tm>='2016-1-1' and tm<'2016-2-1'" -d "orderby=id desc"

甚至可以做統計,比如查看2016年1月裏,列出訪問次數排名前10的地址,以及每個地址訪問了多少次服務器,也可以通過query接口直接查出。
做一個按addr字段的分組統計(gres參數):

curl http://localhost/mysvc/api.php/ApiLog.query -d "gres=addr" -d "res=count(*) cnt" -d "cond=tm>='2016-1-1' and tm<'2016-2-1'" -d "orderby=cnt desc" -d "_pagesz=10"

輸出示例:

[0,{
    "h":["addr","cnt"],
    "d":[["140.206.255.50",1],["101.44.63.119",73],["121.42.0.85",70],...],
    "nextkey": 3
}]

[接口調用的描述方式]

在之後的示例中,我們將使用接口原型來描述一個調用,不再使用curl,比如上面的調用將表示成:

ApiLog.query(gres=addr
    res="count(*) cnt"
    cond="tm>'2016-1-1' and tm<'2016-2-1'"
    orderby="cnt desc"
    _pagesz=10
)
->
{
    "h":["addr","cnt"],
    "d":[["140.206.255.50",1],["101.44.63.119",73],["121.42.0.85",70],...],
    "nextkey": 3
}

返回數據如非特別聲明,我們將只討論調用成功時返回的部分,比如說返回”OK”實際上表示返回[0, "OK"]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章