REST API 使用詳解


REST API 可以讓你用任何支持發送 HTTP 請求的設備來與 LeanCloud 進行交互,你可以使用 REST API 做很多事情,比如:

+

 

  • 一個移動網站可以通過 JavaScript 來獲取 LeanCloud 上的數據.
  • 一個網站可以展示來自 LeanCloud 的數據。
  • 你可以上傳大量的數據,之后可以被一個移動 App 讀取。
  • 你可以下載最近的數據來進行你自定義的分析統計。
  • 使用任何語言寫的程序都可以操作 LeanCloud 上的數據。
  • 如果你不再需要使用 LeanCloud,你可以導出你所有的數據。

API 版本

版本 內容
1.1 2014 年 8 月 13 號發布,修復 Date 類型和 createdAt、updatedAt 的時區問題,返回標准 UTC 時間。
1.0 存在時間不准確的 Bug,實際返回的 Date 類型和 createdAt、updatedAt 都是北京時間。不推薦再使用。

在線測試

API 在線測試工具,目前僅支持調試中國節點下的應用。

4

 

對象

URL HTTP 功能
/1.1/classes/<className> POST 創建對象
/1.1/classes/<className>/<objectId> GET 獲取對象
/1.1/classes/<className>/<objectId> PUT 更新對象
/1.1/classes/<className> GET 查詢對象
/1.1/cloudQuery GET 使用 CQL 查詢對象
/1.1/classes/<className>/<objectId> DELETE 刪除對象
/1.1/scan/classes/<className> GET 按照特定順序遍歷 Class

用戶

URL HTTP 功能
/1.1/users POST 用戶注冊
用戶連接
/1.1/usersByMobilePhone POST 使用手機號碼注冊或登錄
/1.1/login POST 用戶登錄
/1.1/users/<objectId> GET 獲取用戶
/1.1/users/me GET 根據 sessionToken 獲取用戶信息
/1.1/users/<objectId>/refreshSessionToken PUT 重置用戶 sessionToken。
/1.1/users/<objectId>/updatePassword PUT 更新密碼,要求輸入舊密碼。
/1.1/users/<objectId> PUT 更新用戶
用戶連接
驗證Email
/1.1/users GET 查詢用戶
/1.1/users/<objectId> DELETE 刪除用戶
/1.1/requestPasswordReset POST 請求密碼重設
/1.1/requestEmailVerify POST 請求驗證用戶郵箱
/1.1/requestMobilePhoneVerify POST 請求發送用戶手機號碼驗證短信
/1.1/verifyMobilePhone/<code> POST 使用"驗證碼"驗證用戶手機號碼
/1.1/requestChangePhoneNumber POST 請求發送手機短信驗證碼以綁定或更新手機號。
/1.1/changePhoneNumber POST 驗證手機短信驗證碼並綁定或更新手機號。
/1.1/requestLoginSmsCode POST 請求發送手機號碼登錄短信。
/1.1/requestPasswordResetBySmsCode POST 請求發送手機短信驗證碼重置用戶密碼。
/1.1/resetPasswordBySmsCode/<code> PUT 驗證手機短信驗證碼並重置密碼。

角色

URL HTTP 功能
/1.1/roles POST 創建角色
/1.1/roles/<objectId> GET 獲取角色
/1.1/roles/<objectId> PUT 更新角色
/1.1/roles GET 查詢角色
/1.1/roles/<objectId> DELETE 刪除角色

推送通知

URL HTTP 功能
/1.1/push POST 推送通知

安裝數據

URL HTTP 功能
/1.1/installations POST 上傳安裝數據
/1.1/installations/<objectId> GET 獲取安裝數據
/1.1/installations/<objectId> PUT 更新安裝數據
/1.1/installations GET 查詢安裝數據
/1.1/installations/<objectId> DELETE 刪除安裝數據

數據 Schema

URL HTTP 功能
/1.1/schemas GET 獲取應用的所有 Class 的 Schema
/1.1/schemas/<className> POST 獲取應用指定的 Class 的 Schema

雲函數

URL HTTP 功能
/1.1/functions/<functionName> POST 調用雲函數
/1.1/call/<functionName> POST 調用雲函數,支持 AVObject 作為參數和結果

用戶反饋組件

URL HTTP 功能
/1.1/feedback POST 提交新的用戶反饋

即時通訊

URL HTTP 功能
/1.1/rtm/messages/logs GET 獲得應用聊天記錄
/1.1/rtm/messages POST 通過 API 向用戶發消息
/1.1/rtm/transient_group/onlines GET 獲取暫態對話(聊天室)的在線人數

其他 API

URL HTTP 功能
/1.1/date GET 獲得服務端當前時間
/1.1/exportData POST 請求導出應用數據
/1.1/exportData/<id> GET 獲取導出數據任務狀態和結果

請求格式

對於 POST 和 PUT 請求,請求的主體必須是 JSON 格式,而且 HTTP header 的 Content-Type 需要設置為 application/json

+

 

用戶驗證通過 HTTP header 來進行,X-LC-Id 標明正在運行的是哪個應用,X-LC-Key 用來授權鑒定 endpoint:

+

 

curl -X PUT \ -H "X-LC-Id: FFnN2hso42Wego3pWq4X5qlu" \ -H "X-LC-Key: UtOCzqb67d3sN12Kts4URwy8" \ -H "Content-Type: application/json" \ -d '{"content": "更新一篇博客的內容"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>
 

對於 JavaScript 使用,LeanCloud 支持跨域資源共享,所以你可以將這些 header 同 XMLHttpRequest 一同使用。

2

 

更安全的鑒權方式

我們還支持一種新的 API 鑒權方式,即在 HTTP header 中使用 X-LC-Sign 來代替 X-LC-Key,以降低 App Key 的泄露風險。例如:

4

 

curl -X PUT \ -H "X-LC-Id: FFnN2hso42Wego3pWq4X5qlu" \ -H "X-LC-Sign: d5bcbb897e19b2f6633c716dfdfaf9be,1453014943466" \ -H "Content-Type: application/json" \ -d '{"content": "在 HTTP header 中使用 X-LC-Sign 來更新一篇博客的內容"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>
 

X-LC-Sign 的值是由 sign,timestamp[,master] 組成的字符串:

+

 

取值 約束 描述
sign 必須 將 timestamp 加上 App Key 或 Master Key 組成的字符串,再對它做 MD5 簽名后的結果。
timestamp 必須 客戶端產生本次請求的 unix 時間戳(UTC),精確到毫秒。
master 可選 字符串 "master",當使用 master key 簽名請求的時候,必須加上這個后綴明確說明是使用 master key。

舉例來說,假設應用的信息如下:

+

 

App Id FFnN2hso42Wego3pWq4X5qlu
App Key UtOCzqb67d3sN12Kts4URwy8
Master Key DyJegPlemooo4X1tg94gQkw1
請求時間 2016-01-17 15:15:43.466
timestamp 1453014943466

使用 App Key 來計算 sign:

+

 

md5( timestamp + App Key ) 
= md5( 1453014943466UtOCzqb67d3sN12Kts4URwy8 )
= d5bcbb897e19b2f6633c716dfdfaf9be

+

 

 -H "X-LC-Sign: d5bcbb897e19b2f6633c716dfdfaf9be,1453014943466" \
 

使用 Master Key 來計算 sign:

+

 

md5( timestamp + Master Key )
= md5( 1453014943466DyJegPlemooo4X1tg94gQkw1 ) 
= e074720658078c898aa0d4b1b82bdf4b

+

 

 -H "X-LC-Sign: e074720658078c898aa0d4b1b82bdf4b,1453014943466,master" \
 

(最后加上 master 來告訴服務器這個簽名是使用 master key 生成的。)

+

 

使用 master key 將繞過所有權限校驗,應該確保只在可控環境中使用,比如自行開發的管理平台,並且要完全避免泄露。因此,以上兩種計算 sign 的方法可以根據實際情況來選擇一種使用。

響應格式

對於所有的請求,響應格式都是一個 JSON 對象。

+

 

一個請求是否成功是由 HTTP 狀態碼標明的。一個 2XX 的狀態碼表示成功,而一個 4XX 表示請求失敗。當一個請求失敗時響應的主體仍然是一個 JSON 對象,但是總是會包含 code 和 error 這兩個字段,你可以用它們來進行調試。舉個例子,如果嘗試用非法的屬性名來保存一個對象會得到如下信息:

+

 

{ "code": 105, "error": "invalid field name: bl!ng" }
 

錯誤代碼請看 錯誤代碼詳解

+

 

對象

對象格式

LeanCloud 的數據存儲服務是建立在 AVObject(對象)基礎上的,每個 AVObject 包含若干屬性值對(key-value,也稱「鍵值對」),屬性的值是與 JSON 格式兼容的數據。 通過 REST API 保存對象需要將對象的數據通過 JSON 來編碼。這個數據是無模式化的(schema free),這意味着你不需要提前標注每個對象上有哪些 key,你只需要隨意設置鍵值對就可以,后端會保存它。

+

 

舉個例子,假如我們要實現一個類似於微博的社交 App,主要有三類數據:賬戶、帖子、評論,一條微博帖子可能包含下面幾個屬性:

+

 

{ "content": "每個 Java 程序員必備的 8 個開發工具", "pubUser": "LeanCloud官方客服", "pubTimestamp": 1435541999 }
 

Key(屬性名)必須是字母和數字組成的字符串,Value(屬性值)可以是任何可以 JSON 編碼的數據。

+

 

每個對象都有一個類名,你可以通過類名來區分不同的數據。例如,我們可以把微博的帖子對象稱之為 Post。我們建議將類和屬性名分別按照 NameYourClassesLikeThis 和 nameYourKeysLikeThis 這樣的慣例來命名,即區分第一個字母的大小寫,這樣可以提高代碼的可讀性和可維護性。

+

 

當你從 LeanCloud 中獲取對象時,一些字段會被自動加上,如 createdAt、updatedAt 和 objectId。這些字段的名字是保留的,值也不允許修改。我們上面設置的對象在獲取時應該是下面的樣子:

+

 

{ "content": "每個 Java 程序員必備的 8 個開發工具", "pubUser": "LeanCloud官方客服", "pubTimestamp": 1435541999, "createdAt": "2015-06-29T01:39:35.931Z", "updatedAt": "2015-06-29T01:39:35.931Z", "objectId": "558e20cbe4b060308e3eb36c" }
 

createdAt 和 updatedAt 都是 UTC 時間戳,以 ISO 8601 標准和毫秒級精度儲存:YYYY-MM-DDTHH:MM:SS.MMMZ。objectId 是一個字符串,在類中可以唯一標識一個實例。 在 REST API 中,class 級的操作都是通過一個帶類名的資源路徑(URL)來標識的。例如,如果類名是 Post,那么 class 的 URL 就是:

1

 

https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post
 

對於用戶賬戶這種對象,有一個特殊的 URL:

+

 

https://{{appid 前八位}}.api.lncld.net/1.1/users
 

針對於一個特定的對象的操作可以通過組織一個 URL 來做。例如,對 Post 中的一個 objectId 為 558e20cbe4b060308e3eb36c 的對象的操作應使用如下 URL:

+

 

https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>
 

創建對象

為了在 LeanCloud 上創建一個新的對象,應該向 class 的 URL 發送一個 POST 請求,其中應該包含對象本身。class 的名稱必須以字母開頭,只能包含字母、數字和下划線。例如,要創建如上所說的對象:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"content": "每個 Java 程序員必備的 8 個開發工具","pubUser": "LeanCloud官方客服","pubTimestamp": 1435541999}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

當創建成功時,HTTP 的返回是 201 Created,而 header 中的 Location 表示新的 object 的 URL:

+

 

Status: 201 Created Location: https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>
 

響應的主體是一個 JSON 對象,包含新的對象的 objectId 和 createdAt 時間戳。

+

 

{ "createdAt": "2015-06-29T01:39:35.931Z", "objectId": "558e20cbe4b060308e3eb36c" }
 

如果希望返回新創建的對象的完整信息,可以在 URL 里加上 fetchWhenSave 選項,並且設置為 true:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"content": "每個 Java 程序員必備的 8 個開發工具","pubUser": "LeanCloud官方客服","pubTimestamp": 1435541999}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post?fetchWhenSave=true

fetchWhenSave 選項對更新對象也同樣有效,但是它僅返回已被更新的字段,而非全部字段。

+

 

每個應用最多可以創建 500 個 class,但每個 class 中的記錄數量沒有限制。

+

 

獲取對象

當你創建了一個對象時,你可以通過發送一個 GET 請求到返回的 header 的 Location 以獲取它的內容。例如,為了得到我們上面創建的對象:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

返回的主體是一個 JSON 對象包含所有用戶提供的 field 加上 createdAt、updatedAt 和 objectId 字段:

+

 

{ "content": "每個 Java 程序員必備的 8 個開發工具", "pubUser": "LeanCloud官方客服", "pubTimestamp": 1435541999, "createdAt": "2015-06-29T01:39:35.931Z", "updatedAt": "2015-06-29T01:39:35.931Z", "objectId": "558e20cbe4b060308e3eb36c" }
 

當獲取的對象有指向其子對象的指針時,你可以加入 include 選項來獲取這些子對象。假設微博記錄中有一個字段 author 來指向發布者的賬戶信息,按上面的例子,可以這樣來連帶獲取發布者完整信息:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'include=author' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

更新對象

為了更改一個對象已經有的數據,你可以發送一個 PUT 請求到對象相應的 URL 上,任何你未指定的 key 都不會更改,所以你可以只更新對象數據的一個子集。例如,我們來更改我們對象的一個 content 字段:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"content": "每個 JavaScript 程序員必備的 8 個開發工具: http://buzzorange.com/techorange/2015/03/03/9-javascript-ide-editor/"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

返回的 JSON 對象只會包含一個 updatedAt 字段,表明更新發生的時間:

+

 

{ "updatedAt": "2015-06-30T18:02:52.248Z" }
 

計數器

比如一條微博,我們需要記錄有多少人喜歡或者轉發了它,但可能很多次喜歡都是同時發生的,如果每個客戶端都直接把讀到的計數值更改之后再寫回去,那么極容易引發沖突和覆蓋,導致最終結果不准。LeanCloud 提供了對數字類型字段進行原子增加或者減少的功能,穩妥地實現對計數器類型數據的更新:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"upvotes":{"__op":"Increment","amount":1}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

這樣就將對象的 upvotes 屬性值(被用戶點贊的次數)加上 1,其中 amount 為遞增的數字大小,如果為負數,則為遞減。

+

 

除了 Increment,我們也提供了 Decrement 用於遞減,等價於 Increment 一個負數。

+

 

位運算

如果數據表的某一列是整型,可以使用位運算操作符該列進行原子的位運算:

+

 

  • BitAnd 與運算
  • BitOr 或運算
  • BitXor 異或運算
curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"flags":{"__op":"BitOr","value": 0x0000000000000004}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

數組

LeanCloud 提供 3 種原子性操作來存儲和更改數組類型的字段:

+

 

  • Add:在一個數組字段的后面添加一些指定的對象(包裝在一個數組內)
  • AddUnique:只會在數組內原本沒有這個對象的情形下才會添加入數組,插入的位置不定。
  • Remove:從一個數組內移除所有的指定的對象

每種操作都有一個 key objects,其值為被添加或刪除的對象列表。例如為每條微博增加一個「標簽」屬性 tags,然后往里面加入一些值:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"tags":{"__op":"AddUnique","objects":["Frontend","JavaScript"]}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

按條件更新對象

假設從某個賬戶對象 Account 的余額中扣除一定金額,但是要求余額要大於等於被扣除的金額才允許操作,那么就需要通過 where 參數為更新操作加上限定條件 balance >= amount

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"balance":{"__op":"Decrement","amount": 30}}' \ "https://{{appid 前八位}}.api.lncld.net/1.1/classes/Account/558e20cbe4b060308e3eb36c?where=%7B%22balance%22%3A%7B%22%24gte%22%3A%2030%7D%7D"

URL 中 where 參數的值是 %7B%22balance%22%3A%7B%22%24gte%22%3A%2030%7D%7D,其實這是 {"balance":{"$gte": 30}} 被 URL 編碼后的結果。更多 where 查詢的例子請參考 查詢

+

 

如果條件不滿足,更新將失敗,同時返回錯誤碼 305

+

 

{ "code" : 305, "error": "No effect on updating/deleting a document." }
 

特別強調:where 一定要作為 URL 的 Query Parameters 傳入。

+

 

__op 操作匯總

使用 __op("操作名稱", {JSON 參數}) 函數可以完成原子性操作,確保數據的一致性。

+

 

操作 說明 示例
Delete 刪除對象的一個屬性 __op('Delete', {})
Add 在數組末尾添加對象 __op('Add',{'objects':['Apple','Google']})
AddUnique 在數組末尾添加不會重復的對象,插入位置不定。 __op('AddUnique', {'objects':['Apple','Google']})
Remove 從數組中刪除對象 __op('Remove',{'objects':['Apple','Google']})
AddRelation 添加一個關系 __op('AddRelation', {'objects':[pointer('_User','558e20cbe4b060308e3eb36c')]})
RemoveRelation 刪除一個關系 __op('RemoveRelation', {'objects':[pointer('_User','558e20cbe4b060308e3eb36c')]})
Increment 遞增 __op('Increment', {'amount': 50})
Decrement 遞減 __op('Decrement', {'amount': 50})
BitAnd 與運算 __op('BitAnd', {'value': 0x0000000000000004})
BitOr 或運算 __op('BitOr', {'value': 0x0000000000000004})
BitXor 異或運算 __op('BitXor', {'value': 0x0000000000000004})

刪除對象

為了在 LeanCloud 上刪除一個對象,可以發送一個 DELETE 請求到指定的對象的 URL,比如:

+

 

curl -X DELETE \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

還可以使用 Delete 操作刪除一個對象的一個字段(注意此時 HTTP Method 還是 PUT):

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"downvotes":{"__op":"Delete"}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

按條件刪除對象

為請求增加 where 參數即可以按指定的條件來刪除對象。例如刪除點擊量 clicks 為 0 的帖子:

+

 

curl -X DELETE \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ "https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>?where=%7B%22clicks%22%3A%200%7D"

URL 中 where 參數的值是 %7B%22clicks%22%3A%200%7D,其實這是 {"clicks": 0} 被 URL 編碼后的結果。更多 where 查詢的例子請參考 查詢

+

 

如果條件不滿足,刪除將失敗,同時返回錯誤碼 305

+

 

{ "code" : 305, "error": "No effect on updating/deleting a document." }
 

特別強調:where 一定要作為 URL 的 Query Parameters 傳入。

+

 

遍歷 Class

因為更新和刪除都是基於單個對象的,都要求提供 objectId,但是有時候用戶需要高效地遍歷一個 Class,做一些批量的更新或者刪除的操作。

+

 

通常情況下,如果 Class 的數量規模不大,使用查詢加上 skip 和 limit 分頁配合排序 order 就可以遍歷所有數據。但是當 Class 數量規模比較大的時候, skip 的效率就非常低了(這跟 MySQL 等關系數據庫的原因一樣,深度翻頁比較慢),因此我們提供了 scan 協議,可以按照特定字段排序來高效地遍歷一張表,默認這個字段是 objectId 升序,同時支持設置 limit 限定每一批次的返回數量,默認 limit 為 100,最大可設置為 1000:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -G \ --data-urlencode 'limit=10' \ https://{{appid 前八位}}.api.lncld.net/1.1/scan/classes/Article

scan 強制要求使用 master key。

+

 

返回:

+

 

{ "results": [ { "tags" : ["clojure","\u7b97\u6cd5"], "createdAt": "2016-07-07T08:54:13.250Z", "updatedAt": "2016-07-07T08:54:50.268Z", "title" : "clojure persistent vector", "objectId" : "577e18b50a2b580057469a5e" }, ... ], "cursor": "pQRhIrac3AEpLzCA"}
 

其中 results 對應的就是返回的對象列表,而 cursor 表示本次遍歷當前位置的「指針」,當 cursor 為 null 的時候,表示已經遍歷完成,如果不為 null,請繼續傳入 cursor 到 scan 接口就可以從上次到達的位置繼續往后查找:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -G \ --data-urlencode 'limit=10' \ --data-urlencode 'cursor=pQRhIrac3AEpLzCA' \ https://{{appid 前八位}}.api.lncld.net/1.1/scan/classes/Article

每次返回的 cursor 的有效期是 10 分鍾。

+

 

遍歷還支持過濾條件,加入 where 參數:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -G \ --data-urlencode 'limit=10' \ --data-urlencode 'where={"score": 100}' \ https://{{appid 前八位}}.api.lncld.net/1.1/scan/classes/Article

默認情況下系統按 objectId 升序排序,增加 scan_key 參數可以使用其他字段來排序:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -G \ --data-urlencode 'limit=10' \ --data-urlencode 'scan_key=score' \ https://{{appid 前八位}}.api.lncld.net/1.1/scan/classes/Article

scan_key 也支持倒序,前面加個減號即可,例如 -score

+

 

自定義的 scan_key 需要滿足嚴格單調遞增的條件,並且 scan_key 不可作為 where 查詢條件存在。

+

 

批量操作

為了減少網絡交互的次數太多帶來的時間浪費,你可以在一個請求中對多個對象進行 create、update、delete 操作。

+

 

在一個批次中每一個操作都有相應的方法、路徑和主體,這些參數可以代替你通常會使用的 HTTP 方法。這些操作會以發送過去的順序來執行,比如我們要一次發布一系列的微博:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "requests": [ { "method": "POST", "path": "/1.1/classes/Post", "body": { "content": "近期 LeanCloud 的文檔已經支持評論功能,如果您有疑問、意見或是其他想法,都可以直接在我們文檔中提出。", "pubUser": "LeanCloud官方客服" } }, { "method": "POST", "path": "/1.1/classes/Post", "body": { "content": "很多用戶表示很喜歡我們的文檔風格,我們已將 LeanCloud 所有文檔的 Markdown 格式的源碼開放出來。", "pubUser": "LeanCloud官方客服" } } ] }' \ https://{{appid 前八位}}.api.lncld.net/1.1/batch

我們對每一批次中所包含的操作數量(requests 數組中的元素個數)暫不設限,但考慮到雲端對每次請求的 body 內容大小有 20 MB 的限制,因此建議將每一批次的操作數量控制在 100 以內。

+

 

批量操作的響應 body 會是一個列表,列表的元素數量和順序與給定的操作請求是一致的。每一個在列表中的元素都有一個字段是 success 或者 error。

+

 

[ { "error": { "code": 1, "error": "Could not find object by id '558e20cbe4b060308e3eb36c' for class 'Post'." } }, { "success": { "updatedAt": "2017-02-22T06:35:29.419Z", "objectId": "58ad2e850ce463006b217888" } } ]
 

需要注意,即使一個 batch 請求返回的響應碼為 200,這僅代表服務端已收到並處理了這個請求,但並不說明該 batch 中的所有操作都成功完成,只有當返回 body 的列表中不存在 error 元素,開發者才可以認為所有操作都已成功完成。

+

 

在 batch 操作中 update 和 delete 同樣是有效的:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "requests": [ { "method": "PUT", "path": "/1.1/classes/Post/55a39634e4b0ed48f0c1845b", "body": { "upvotes": 2 } }, { "method": "DELETE", "path": "/1.1/classes/Post/55a39634e4b0ed48f0c1845c" } ] }' \ https://{{appid 前八位}}.api.lncld.net/1.1/batch

批量操作還有一個冷門用途,代替 URL 過長的 GET(比如使用 containedIn 等方法構造查詢)和 DELETE (比如批量刪除)請求,以繞過服務端和某些客戶端對 URL 長度的限制。

+

 

數據類型

到現在為止我們只使用了可以被標准 JSON 編碼的值,LeanCloud 移動客戶端 SDK library 同樣支持日期、二進制數據和關系型數據。在 REST API 中,這些值都被編碼了,同時有一個 __type 字段(注意:前綴是兩個下划線)來標示出它們的類型,所以如果你采用正確的編碼的話就可以讀或者寫這些字段。

+

 

Date 類型包含了一個 iso 字段,其值是一個 UTC 時間戳,以 ISO 8601 格式和毫秒級的精度來存儲的時間值,格式為:YYYY-MM-DDTHH:MM:SS.MMMZ

+

 

{ "__type": "Date", "iso": "2015-06-21T18:02:52.249Z" }
 

Date 和內置的 createdAt 字段和 updatedAt 字段相結合的時候特別有用,舉個例子:為了找到在一個特殊時間發布的微博,只需要將 Date 編碼后放在使用了比較條件的查詢里面:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={"createdAt":{"$gte":{"__type":"Date","iso":"2015-06-21T18:02:52.249Z"}}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

注意,由於 createdAt 和 updatedAt 屬於保留字段,因此通過 REST API 請求這兩個字段時,將直接返回 UTC 時間戳字符串。

+

 

Byte 類型包含了一個 base64 字段,這個字段是一些二進制數據編碼過的 base64 字符串。base64 是 MIME 使用的標准,不包含空白符:

+

 

{ "__type": "Bytes", "base64": "5b6I5aSa55So5oi36KGo56S65b6I5Zac5qyi5oiR5Lus55qE5paH5qGj6aOO5qC877yM5oiR5Lus5bey5bCGIExlYW5DbG91ZCDmiYDmnInmlofmoaPnmoQgTWFya2Rvd24g5qC85byP55qE5rqQ56CB5byA5pS+5Ye65p2l44CC" }
 

Pointer 類型是用來設定 AVObject 作為另一個對象的值時使用的,它包含了 className 和 objectId 兩個屬性值,用來提取目標對象:

+

 

{ "__type": "Pointer", "className": "Post", "objectId": "55a39634e4b0ed48f0c1845c" }
 

指向用戶對象的 Pointer 的 className 為 _User,前面加一個下划線表示開發者不能定義的類名,而且所指的類是 LeanCloud 平台內置的。

+

 

Relation 類型被用在多對多的類型上,移動端使用 AVRelation 作為值,它有一個 className 字段表示目標對象的類名。

+

 

Relation 類型已被棄用。請使用 中間表 來完成對關聯數據的查詢、排序等復雜操作。

+

 

{ "__type": "Relation", "className": "Post" }
 

在進行查詢時,Relation 對象的行為很像是 Pointer 的數組,任何針對於 pointer 數組的操作(include 除外)都可以對 Relation 起作用。

+

 

當更多的數據類型被加入的時候,它們都會采用 hashmap 加上一個 __type 字段的形式,所以你不應該使用 __type 作為你自己的 JSON 對象的 key。

+

 

查詢

基礎查詢

通過發送一個 GET 請求到類的 URL 上,不需要任何 URL 參數,你就可以一次獲取多個對象。下面就是簡單地獲取所有微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

返回的值就是一個 JSON 對象包含了 results 字段,它的值就是對象的列表:

+

 

{ "results": [ { "content": "近期 LeanCloud 的文檔已經支持評論功能,如果您有疑問、意見或是其他想法,都可以直接在我們文檔中提出。", "pubUser": "LeanCloud官方客服", "upvotes": 2, "createdAt": "2015-06-29T03:43:35.931Z", "objectId": "55a39634e4b0ed48f0c1845b" }, { "content": "每個 Java 程序員必備的 8 個開發工具", "pubUser": "LeanCloud官方客服", "pubTimestamp": 1435541999, "createdAt": "2015-06-29T01:39:35.931Z", "updatedAt": "2015-06-29T01:39:35.931Z", "objectId": "558e20cbe4b060308e3eb36c" } ] }
 

注:應用控制台對 createdAt 和 updatedAt 做了在展示優化,它們會依據用戶操作系統時區而顯示為本地時間;客戶端 SDK 獲取到這些時間后也會將其轉換為本地時間;而通過 REST API 獲取到的則是原始的 UTC 時間,開發者可能需要根據情況做相應的時區轉換。

+

 

查詢約束

通過 where 參數的形式可以對查詢對象做出約束。

+

 

where 參數的值應該是 JSON 編碼過的。就是說,如果你查看真正被發出的 URL 請求,它應該是先被 JSON 編碼過,然后又被 URL 編碼過。最簡單的使用 where 參數的方式就是包含應有的 key 和 value。例如,如果我們想要看到「LeanCloud官方客服」發布的所有微博,我們應該這樣構造查詢:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={"pubUser":"LeanCloud官方客服"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

除了完全匹配一個給定的值以外,where 也支持比較的方式,而且它還支持對 key 的一些 hash 操作,比如包含。where 參數支持如下選項:

+

 

Key Operation
$ne 不等於
$lt 小於
$lte 小於等於
$gt 大於
$gte 大於等於
$regex 正則表達式。$options 指定 全局修飾符
$in 包含任意一個數組值
$nin 不包含任意一個數組值
$all 包括所有的數組值
$exists 指定 Key 有值
$select 匹配另一個查詢的返回值
$dontSelect 排除另一個查詢的返回值

例如獲取在 2015-06-29 當天發布的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={"createdAt":{"$gte":{"__type":"Date","iso":"2015-06-29T00:00:00.000Z"},"$lt":{"__type":"Date","iso":"2015-06-30T00:00:00.000Z"}}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

求點贊次數少於 10 次,且該次數還是奇數的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={"upvotes":{"$in":[1,3,5,7,9]}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

獲取不是「LeanCloud官方客服」發布的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={"pubUser":{"$nin":["LeanCloud官方客服"]}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

獲取有人喜歡的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={"upvotes":{"$exists":true}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

獲取沒有被人喜歡過的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={"upvotes":{"$exists":false}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

微博有用戶互相關注的功能,如果我們用 _Followee(用戶關注的人) 和 _Follower(用戶的粉絲) 這兩個類來存儲用戶之間的關注關系(我們的 應用內社交組件 已經實現了這樣的模型),我們可以創建一個查詢來找到某個用戶關注的人發布的微博(Post 表中有一個字段 author 指向發布者):

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={ "author": { "$select": { "query": { "className":"_Followee", "where": { "user":{ "__type": "Pointer", "className": "_User", "objectId": "55a39634e4b0ed48f0c1845c" } } }, "key":"followee" } } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

order 參數指定一個字段的排序方式,前面加一個負號表示逆序。返回 Post 記錄並按發布時間升序排列:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'order=createdAt' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

降序排列:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'order=-createdAt' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

對多個字段進行排序,要使用逗號分隔的列表。將 Post 以 createdAt 升序和 pubUser 降序進行排序:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'order=createdAt,-pubUser' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

你可以用 limit 和 skip 來做分頁。limit 的默認值是 100,任何 1 到 1000 之間的值都是可選的,在 1 到 1000 范圍之外的都強制轉成默認的 100。比如為了獲取排序在 400 到 600 之間的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'limit=200' \ --data-urlencode 'skip=400' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

你可以限定返回的字段通過傳入 keys 參數和一個逗號分隔列表。為了返回對象只包含 pubUser 和 content 字段(還有特殊的內置字段比如 objectId、createdAt 和 updatedAt):

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'keys=pubUser,content' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

keys 還支持反向選擇,也就是不返回某些字段,字段名前面加個減號即可,比如我不想查詢返回 author

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'keys=-author' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

所有以上這些參數都可以和其他的組合進行使用。

+

 

正則查詢

獲取標題以大寫「WTO」開頭的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -G \ --data-urlencode 'where={"title":{"$regex":"^WTO.*","$options":"i"}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

我們使用以下數據來演示如何使用 $options 匹配 title 字段值:

+

 

{ "_id" : 100, "title" : "Single line description." }, { "_id" : 101, "title" : "First line\nSecond line" }, { "_id" : 102, "title" : "Many spaces before line" }, { "_id" : 103, "title" : "Multiple\nline description" }, { "_id" : 103, "title" : "abc123" }
 
參數 說明 示例
i 忽略大小寫 {"$regex":"single", "$options":"i"} 將匹配

{ "_id" : 100, "title" : "Single line description." }
 
m 多行匹配
比如文本中包含了換行符 \n
{"$regex":"^S", "$options":"m"}(以大寫字母 S 開頭)將匹配 

{ "_id" : 100, "title" : "Single line description." },
{ "_id" : 101, "title" : "First line\nSecond line" }
 
x 忽略空白字符
包括空格、tab、\n#注釋等,
但對 vertical tab(ASCII 碼為 11)無效。
{"$regex":"abc #category code\n123 #item number", "$options":"x"}(# 后面為注釋)將匹配 

{ "_id" : 103, "title" : "abc123" }
 
s 允許 . 匹配任意字符和換行 {"$regex":"m.*line", "$options":"si"} 將匹配 

{ "_id" : 102, "title" : "Many spaces before line" },
{ "_id" : 103, "title" : "Multiple\nline description" }
 

以上參數可以組合使用,如 "$options":"sixm"

+

 

數組查詢

如果 key 的值是數組類型,查找 key 值中有 2 的對象:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={"arrayKey":2}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/TestObject

查找 key 值中有 2 或 3 或 4 的對象:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={"arrayKey":{"$in":[2,3,4]}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/TestObject

使用 $all 操作符來找到 key 值中同時有 2 和 3 和 4 的對象:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={"arrayKey":{"$all":[2,3,4]}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/TestObject

關系查詢

有幾種方式來查詢對象之間的關系數據。如果你想獲取對象,而這個對象的一個字段對應了另一個對象,你可以用一個 where 查詢,自己構造一個 Pointer,和其他數據類型一樣。例如,每條微博都會有很多人評論,我們可以讓每一個 Comment 將它對應的 Post 對象保存到 post 字段上,這樣你可以取得一條微博下所有 Comment:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={"post":{"__type":"Pointer","className":"Post","objectId":"558e20cbe4b060308e3eb36c"}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Comment

如果你想獲取對象,這個對象的一個字段指向的對象需要另一個查詢來指定,你可以使用 $inQuery 操作符。注意 limit 的默認值是 100 且最大值是 1000,這個限制同樣適用於內部的查詢,所以對於較大的數據集你可能需要細心地構建查詢來獲得期望的結果。

+

 

如上面的例子,假設每條微博還有一個 image 的字段,用來存儲配圖,你可以這樣列出帶圖片的微博的評論數據:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={"post":{"$inQuery":{"where":{"image":{"$exists":true}},"className":"Post"}}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Comment

如果你想獲取作為其父對象的關系成員的對象,你可以使用 $relatedTo 操作符。例如對於微博這種社交類應用來講,每一條微博都可以被不同的用戶點贊,我們可以設計 Post 類下面有一個 key 是 Relation 類型,叫做 likes,存儲了喜歡這個 Post 的所有 User。

+

 

Relation 類型已被棄用。請使用 中間表 來完成對關聯數據的查詢、排序等復雜操作。

+

 

你可以通過下面的方式找到喜歡某條 Post 的所有用戶(請注意,新創建應用的 _User 表的查詢權限默認是關閉的,你可以通過 class 權限設置打開,請參考 數據與安全 - Class 級別的權限。):

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={"$relatedTo":{"object":{"__type":"Pointer","className":"Post","objectId":"558e20cbe4b060308e3eb36c"},"key":"likes"}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/users

有時候,你可能需要在一個查詢之中返回多種類型,你可以通過傳入字段到 include 參數中。比如,我們想獲得最近的 10 篇評論,而你想同時得到它們關聯的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'order=-createdAt' \ --data-urlencode 'limit=10' \ --data-urlencode 'include=post' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Comment

不是作為一個 Pointer 表示,post 字段現在已經被展開為一個完整的對象:__type 被設置為 Object 而 className 同樣也被提供了。例如,一個指向 Post 的 Pointer 可能被展示為:

+

 

{ "__type": "Pointer", "className": "Post", "objectId": "51e3a359e4b015ead4d95ddc" }
 

當一個查詢使用 include 參數來包含進去來取代 pointer 之后,可以看到 pointer 被展開為:

+

 

{ "__type": "Object", "className": "Post", "objectId": "51e3a359e4b015ead4d95ddc", "createdAt": "2015-06-29T09:31:20.371Z", "updatedAt": "2015-06-29T09:31:20.371Z", "desc": "Post 的其他字段也會一同被包含進來。" }
 

你可以同樣做多層的 include,這時要使用點號(.)。如果你要 include 一個 Comment 對應的 Post 對應的 author

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'order=-createdAt' \ --data-urlencode 'limit=10' \ --data-urlencode 'include=post.author' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Comment

如果你要構建一個查詢,這個查詢要 include 多個類,此時用逗號分隔列表即可。

+

 

對象計數

如果你在使用 limit,或者如果返回的結果很多,你可能想要知道到底有多少對象應該返回,而不用把它們全部獲得以后再計數,此時你可以使用 count 參數。舉個例子,如果你僅僅是關心一個某個用戶發布了多少條微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={"pubUser":"LeanCloud官方客服"}' \ --data-urlencode 'count=1' \ --data-urlencode 'limit=0' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

因為這個 request 請求了 count 而且把 limit 設為了 0,返回的值里面只有計數,沒有 results

+

 

{ "results": [ ], "count": 7 }
 

如果有一個非 0 的 limit 的話,則既會返回 results 也會返回 count

+

 

復合查詢

$or 操作符用於查詢符合任意一種條件的對象,它的值為一個 JSON 數組。例如,查詢企業賬號和個人賬號的微博:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={"$or":[{"pubUserCertificate":{"$gt":2}},{"pubUserCertificate":{"$lt":3}}]}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

任何在查詢上的其他約束都會對返回的對象生效,所以你可以用 $or 對其他的查詢添加約束。

+

 

$and 操作符用於查詢符合全部條件的對象,它的值為一個 JSON 數組。例如查找存在 price 字段且 price != 199 的對象:

+

 

--data-urlencode 'where={"$and":[{"price": {"$ne":199}},{"price":{"$exists":true}}]}' \
 

在組合查詢的子查詢中不支持使用 limit、skip、order、include 等非過濾型的約束。

+

 

使用 CQL 查詢

我們還提供類 SQL 語法的 CQL 查詢語言,查詢應用內數據,例如:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'cql=select * from Post limit 0,100 order by pubUser' \ https://{{appid 前八位}}.api.lncld.net/1.1/cloudQuery

更多請參考 CQL 詳細指南

+

 

CQL 還支持占位符查詢,where 和 limit 子句的條件參數可以使用問號替換,然后通過 pvalues 數組傳入:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'cql=select * from Post where pubUser=? limit ?,? order by createdAt' \ --data-urlencode 'pvalues=["dennis", 0, 100]' https://{{appid 前八位}}.api.lncld.net/1.1/cloudQuery

子查詢的局限

使用子查詢可能會遇到查不到記錄或查到的記錄不全的情況。例如:

+

 

-- 找出積分高於 80region  cn 的玩家記錄 SELECT * FROM player WHERE NAME IN (SELECT NAME FROM gamescore WHERE score > 80) AND region = 'cn'
 

LeanCloud 雲端使用的並非關系型數據庫,無法做到真正的聯表查詢,所以實際的處理方式是:先執行內嵌/子查詢(和普通查詢一樣,limit 默認為 100,最大 1000),然后將子查詢的結果填入主查詢的對應位置,再執行主查詢。

+

 

如果子查詢匹配到了 100 條以上的記錄(性別等區分度低的字段重復值往往較多),且主查詢有其他查詢條件(region = 'cn'),那么可能會出現沒有結果或結果不全的情況,其本質上是子查詢查出的 100 條記錄沒有滿足主查詢的其他條件。

+

 

我們建議采用以下方案進行改進:

+

 

  • 確保子查詢的結果在 100 條以下,如果在 100 - 1000 條的話請在子查詢末尾添加 limit 1000。
  • 將需要查詢的字段冗余到主查詢所在的表上;例如將 score 冗余到 Player 表上,或者將 region 添加到 GameScore 上然后只查 GameScore 表。
  • 進行多次查詢,每次在子查詢上添加 skip 來遍歷所有記錄(注意 skip 的值較大時可能會引發性能問題,因此不是很推薦)。

用戶

不僅在移動應用上,還在其他系統中,很多應用都有一個統一的登錄流程。通過 REST API 訪問用戶的賬戶讓你可以在 LeanCloud 上簡單實現這一功能。

+

 

通常來說,用戶(類名 _User)這個類的功能與其他的對象是相同的,比如都沒有限制模式(Schema free)。User 對象和其他對象不同的是一個用戶必須有用戶名(username)和密碼(password),密碼會被自動地加密和存儲。LeanCloud 強制要求 username 和 email 這兩個字段必須是沒有重復的。

+

 

注冊

注冊一個新用戶與創建一個新的普通對象之間的不同點在於 username 和 password 字段都是必需的。password 字段會以和其他的字段不一樣的方式處理,它在儲存時會被加密而且永遠不會被返回給任何來自客戶端的請求。

+

 

你可以讓 LeanCloud 自動驗證郵件地址,做法是進入 控制台 > 存儲 > 設置 > 用戶賬號,勾選 用戶注冊時,發送驗證郵件。

+

 

這項設置啟用了的話,所有填寫了 email 的用戶在注冊時都會產生一個 email 驗證地址,並發回到用戶郵箱,用戶打開郵箱點擊了驗證鏈接之后,用戶表里 emailVerified 屬性值會被設為 true。你可以在 emailVerified 字段上查看用戶的 email 是否已經通過驗證。

+

 

為了注冊一個新的用戶,需要向 user 路徑發送一個 POST 請求,你可以加入一個新的字段,例如,創建一個新的用戶有一個電話號碼:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"username":"hjiang","password":"f32@ds*@&dsa","phone":"18612340000"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/users

當創建成功時,HTTP返回為 201 Created,Location 頭包含了新用戶的 URL:

+

 

Status: 201 Created Location: https://{{appid 前八位}}.api.lncld.net/1.1/users/55a47496e4b05001a7732c5f
 

返回的主體是一個 JSON 對象,包含 objectId、createdAt 時間戳表示創建對象時間,sessionToken 可以被用來認證這名用戶隨后的請求:

+

 

{ "sessionToken":"qmdj8pdidnmyzp0c7yqil91oc", "createdAt":"2015-07-14T02:31:50.100Z", "objectId":"55a47496e4b05001a7732c5f" }
 

登錄

在你允許用戶注冊之后,在以后你需要讓他們用自己的用戶名和密碼登錄。為了做到這一點,發送一個 POST 請求到 /1.1/login,加上 username 和 password 作為 body。

2

 

curl -X POST \ -H "Content-Type: application/json" \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -d '{"username":"hjiang","password":"f32@ds*@&dsa"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/login

返回的主體是一個 JSON 對象包括所有除了 password 以外的自定義字段。它同樣包含了 createdAt、updateAt、objectId 和 sessionToken 字段。

+

 

{ "sessionToken":"qmdj8pdidnmyzp0c7yqil91oc", "updatedAt":"2015-07-14T02:31:50.100Z", "phone":"18612340000", "objectId":"55a47496e4b05001a7732c5f", "username":"hjiang", "createdAt":"2015-07-14T02:31:50.100Z", "emailVerified":false, "mobilePhoneVerified":false }
 

可以將 sessionToken 理解為用戶的登錄憑證,每個用戶的 sessionToken 在同一個應用內都是唯一的, 類似於 Cookie 的概念。

+

 

正常情況下,用戶的 sessionToken 是固定不變的,但在以下情況下會發生改變:

+

 

在 sessionToken 變化后,已有的登錄如果調用到用戶相關權限受限的 API,將返回 403 權限錯誤。

+

 

已登錄的用戶信息

用戶成功注冊或登錄后,服務器會返回 sessionToken 並保存在本地,后續請求可以通過傳遞 sessionToken 來獲取該用戶信息(如訪問權限等)。更多說明請參考 存儲 · sessionToken

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "X-LC-Session: qmdj8pdidnmyzp0c7yqil91oc" \ https://{{appid 前八位}}.api.lncld.net/1.1/users/me

返回的 JSON 數據與 /login 登錄請求所返回的相同。

+

 

重置登錄 sessionToken

可以主動重置用戶的 sessionToken:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "X-LC-Session: qmdj8pdidnmyzp0c7yqil91oc" \ https://{{appid 前八位}}.api.lncld.net/1.1/users/57e3bcca67f35600577c3063/refreshSessionToken

調用這個 API 要求傳入登錄返回的 X-LC-Session 作為認證,或者使用 Master Key。

+

 

重置成功將返回新的 sessionToken 及用戶信息:

+

 

{ "sessionToken":"5frlikqlwzx1nh3wzsdtfr4q7", "updatedAt":"2016-10-20T03:10:57.926Z", "objectId":"57e3bcca67f35600577c3063", "username":"leancloud", "createdAt":"2016-09-22T11:13:14.842Z", "emailVerified":false, "mobilePhoneVerified":false }
 

賬戶鎖定

輸入錯誤的密碼或驗證碼會導致用戶登錄失敗。如果在 15 分鍾內,同一個用戶登錄失敗的次數大於 6 次,該用戶賬戶即被雲端暫時鎖定,此時雲端會返回錯誤碼 {"code":219,"error":"登錄失敗次數超過限制,請稍候再試,或者通過忘記密碼重設密碼。"},開發者可在客戶端進行必要提示。

+

 

鎖定將在最后一次錯誤登錄的 15 分鍾之后由雲端自動解除,開發者無法通過 SDK 或 REST API 進行干預。在鎖定期間,即使用戶輸入了正確的驗證信息也不允許登錄。這個限制在 SDK 和雲引擎中都有效。

+

 

使用手機號碼注冊或登錄

請參考 短信服務 REST API 詳解 · 使用手機號碼注冊或登錄

+

 

驗證 Email

設置 email 驗證是 app 設置中的一個選項,通過這個標識,應用層可以對提供真實 email 的用戶更好的功能或者體驗。Email 驗證會在 User 對象中加入 emailVerified 字段,當一個用戶的 email 被新設置或者修改過的話,emailVerified 會被重置為 false。LeanCloud 后台會往用戶填寫的郵箱發送一個驗證鏈接,用戶點擊這個鏈接可以讓 emailVerified 被設置為 true。

+

 

emailVerified 字段有 3 種狀態可以參考:

+

 

  1. true:用戶已經點擊了發送到郵箱的驗證地址,郵箱被驗證為真實有效。LeanCloud 保證在新創建用戶的時候 emailVerified 一定為 false。
  2. false:User 對象最后一次被更新的時候,用戶並沒有確認過他的 email 地址。如果你看到 emailVerified 為 false 的話,你可以考慮刷新 User 對象或者再次請求驗證用戶郵箱。
  3. null:User對象在 email 驗證沒有打開的時候就已經創建了,或者 User 沒有 email。

關於自定義郵件模板和驗證鏈接請看博客文章《自定義應用內用戶重設密碼和郵箱驗證頁面》

+

 

請求驗證 Email

發送給用戶的郵箱驗證郵件在一周內失效,你可以通過調用 /1.1/requestEmailVerify 來強制重新發送:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"email":"hang@leancloud.rocks"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/requestEmailVerify

請求密碼重設

在用戶將 email 與他們的賬戶關聯起來之后,你可以通過郵件來重設密碼。操作方法為,發送一個 POST 請求到 /1.1/requestPasswordReset,同時在 request 的 body 部分帶上 email 字段。

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{"email":"hang@leancloud.rocks"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/requestPasswordReset

如果成功的話,返回的值是一個 JSON 對象。

+

 

關於自定義郵件模板和驗證鏈接請看這篇博客文章《自定義應用內用戶重設密碼和郵箱驗證頁面》

+

 

手機號碼驗證

請參考 短信服務 REST API 詳解 - 用戶賬戶與手機號碼驗證

+

 

獲取用戶

你可以發送一個 GET 請求到 URL 以獲取用戶的賬戶信息,返回的內容就是當創建用戶時返回的內容。比如,為了獲取上面創建的用戶:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/users/55a47496e4b05001a7732c5f

返回的 body 是一個 JSON 對象,包含所有用戶提供的字段,除了密碼以外,也包括了 createdAt、 updatedAt 和 objectId 字段.

+

 

{ "updatedAt":"2015-07-14T02:31:50.100Z", "phone":"18612340000", "objectId":"55a47496e4b05001a7732c5f", "username":"hjiang", "createdAt":"2015-07-14T02:31:50.100Z", "emailVerified":false, "mobilePhoneVerified":false }
 

更新用戶

在通常的情況下,沒有人會允許別人來改動他們自己的數據。為了做好權限認證,確保只有用戶自己可以修改個人數據,在更新用戶信息的時候,必須在 HTTP 頭部加入一個 X-LC-Session 項來請求更新,這個 session token 在注冊和登錄時會返回。

+

 

為了改動一個用戶已經有的數據,需要對這個用戶的 URL 發送一個 PUT 請求。任何你沒有指定的 key 都會保持不動,所以你可以只改動用戶數據中的一部分。username 和 password 也是可以改動的,但是新的 username 不能和既有數據重復。

+

 

比如,如果我們想對 「hjiang」 的手機號碼做出一些改動:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "X-LC-Session: qmdj8pdidnmyzp0c7yqil91oc" \ -H "Content-Type: application/json" \ -d '{"phone":"18600001234"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/users/55a47496e4b05001a7732c5f

返回的 body 是一個 JSON 對象,只有一個 updatedAt 字段表明更新發生的時間.

+

 

{ "updatedAt": "2015-07-14T02:35:50.100Z" }
 

安全地修改用戶密碼

修改密碼,可以直接使用上面的PUT /1.1/users/:objectId的 API,但是很多開發者會希望讓用戶輸入一次舊密碼做一次認證,舊密碼正確才可以修改為新密碼,因此我們提供了一個單獨的 API PUT /1.1/users/:objectId/updatePassword 來安全地更新密碼:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "X-LC-Session: qmdj8pdidnmyzp0c7yqil91oc" \ -H "Content-Type: application/json" \ -d '{"old_password":"the_old_password", "new_password":"the_new_password"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/users/55a47496e4b05001a7732c5f/updatePassword
  • old_password:用戶的老密碼
  • new_password:用戶的新密碼

注意:仍然需要傳入 X-LC-Session,也就是登錄用戶才可以修改自己的密碼。

+

 

查詢

請注意,新創建應用的 _User 表的查詢權限默認是關閉的,你可以通過 class 權限設置打開,請參考 數據與安全 - Class 級別的權限

+

 

你可以一次獲取多個用戶,只要向用戶的根 URL 發送一個 GET 請求。沒有任何 URL 參數的話,可以簡單地列出所有用戶:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/users

返回的值是一個 JSON 對象包括一個 results 字段,值是包含了所有對象的一個 JSON 數組。

+

 

{ "results":[ { "updatedAt":"2015-07-14T02:31:50.100Z", "phone":"18612340000", "objectId":"55a47496e4b05001a7732c5f", "username":"hjiang", "createdAt":"2015-07-14T02:31:50.100Z", "emailVerified":false, "mobilePhoneVerified":false } ] }
 

所有的對普通對象的查詢選項都適用於對用戶對象的查詢,所以可以查看 查詢 部分來獲取詳細信息。

+

 

刪除用戶

為了在 LeanCloud 上刪除一個用戶,可以向它的 URL 上發送一個 DELETE 請求。同樣的,你必須提供一個 X-LC-Session 在 HTTP 頭上以便認證。例如:

+

 

curl -X DELETE \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "X-LC-Session: qmdj8pdidnmyzp0c7yqil91oc" \ https://{{appid 前八位}}.api.lncld.net/1.1/users/55a47496e4b05001a7732c5f

連接用戶賬戶和第三方平台

LeanCloud 允許你連接你的用戶到其他服務,比如新浪微博和騰訊微博,這樣就允許你的用戶直接用他們現有的賬號 id 來注冊或登錄你的應用。在進行注冊和登錄時,需要附帶上 authData 字段來提供你希望連接的服務的授權信息。一旦關聯了某個服務,authData 將被存儲到你的用戶信息里。如需重新獲取該內容,請參考 獲取 authData

+

 

authData 是一個普通的 JSON 對象,它所要求的 key 根據 service 不同而不同,具體要求見下面。每種情況下,你都需要自己負責完成整個授權過程(一般是通過 OAuth 協議,1.0 或者 2.0) 來獲取授權信息,提供給連接 API。

+

 

新浪微博 的 authData 內容:

+

 

{ "authData": { "weibo": { "uid": "123456789", "access_token": "2.00vs3XtCI5FevCff4981adb5jj1lXE", "expiration_in": "36000" } } }
 

騰訊微博 的 authData 內容:

+

 

{ "authData": { "qq": { "openid": "0395BA18A5CD6255E5BA185E7BEBA242", "access_token": "12345678-SaMpLeTuo3m2avZxh5cjJmIrAfx4ZYyamdofM7IjU", "expires_in": 1382686496 } } }
 

微信 的 authData 內容:

+

 

{ "authData": { "weixin": { "openid": "0395BA18A5CD6255E5BA185E7BEBA242", "access_token": "12345678-SaMpLeTuo3m2avZxh5cjJmIrAfx4ZYyamdofM7IjU", "expires_in": 1382686496 } } }
 

匿名用戶(Anonymous user)的 authData 內容:

+

 

{ "anonymous": { "id": "random UUID with lowercase hexadecimal digits" } }
 

其他任意第三方平台(其他第三方將不支持校驗 access token 選項):

+

 

 { "第三方平台名稱,例如facebook": { "uid": "在第三方平台上的唯一用戶id字符串", "access_token": "在第三方平台的 access token", ……其他可選屬性 } }
 

同時,請在控制台的 _User 表里為 authData.第三方平台名稱.uid 建立唯一索引,並且勾選上 允許缺失值 選項,這樣才能保證一個第三方賬號只綁定到一個 LeanCloud 應用內用戶上。

+

 

當一個數據表的記錄數超過 1 萬時,開發者將無法自行為其創建索引(此前已創建的索引仍然會對超過 1 萬條的數據生效)。商用版用戶需要通過 工單服務 向我們提交創建申請(選擇「建立索引」分類),開發版用戶需要先升級到商用版才能提交創建申請。

+

 

獲取 authData

authData 的數據默認為僅限其所屬用戶可讀寫,也就是說其他用戶無法以 fetch 或 query 來獲取。要更改這一默認行為,需要進入 應用控制台 > 存儲 > _User 表,點擊 authData 字段右側的箭頭,選擇 編輯,關掉「列屬性」里的「只限所屬用戶讀寫」選項才能獲取到。

+

 

注冊和登錄

使用一個連接服務來注冊用戶並登錄,同樣使用 POST 請求 users,只是需要提供 authData 字段。例如,使用新浪微博賬戶注冊或者登錄用戶:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "authData": { "qq": { "openid": "0395BA18A5CD6255E5BA185E7BEBA242", "access_token": "12345678-SaMpLeTuo3m2avZxh5cjJmIrAfx4ZYyamdofM7IjU", "expires_in": 1382686496 } } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/users

LeanCloud 會校驗提供的 authData 是否有效,並檢查是否已經有一個用戶連接了這個 authData 服務。如果已經有用戶存在並連接了同一個 authData,那么返回 200 OK 和詳細信息(包括用戶的 sessionToken):

+

 

Status: 200 OK Location: https://{{appid 前八位}}.api.lncld.net/1.1/users/75a4800fe4b05001a7745c41
 

應答的 body 類似:

+

 

{ "username": "LeanCloud", "createdAt": "2015-06-28T23:49:36.353Z", "updatedAt": "2015-06-28T23:49:36.353Z", "objectId": "75a4800fe4b05001a7745c41", "sessionToken": "anythingstringforsessiontoken", "authData": { "qq": { "openid": "0395BA18A5CD6255E5BA185E7BEBA242", "access_token": "12345678-SaMpLeTuo3m2avZxh5cjJmIrAfx4ZYyamdofM7IjU", "expires_in": 1382686496 } } }
 

如果用戶還沒有連接到這個賬號,則你會收到 201 Created 的應答狀態碼,標識新的用戶已經被創建:

+

 

Status: 201 Created Location: https://{{appid 前八位}}.api.lncld.net/1.1/users/55a4800fe4b05001a7745c41
 

應答內容包括 objectId、createdAt、sessionToken 以及一個自動生成的隨機 username,例如:

+

 

{ "username":"ec9m07bo32cko6soqtvn6bko5", "sessionToken":"tfrvbzmdf609nu9204v5f0tuj", "createdAt":"2015-07-14T03:20:47.733Z", "objectId":"55a4800fe4b05001a7745c41" }
 

UnionID 注冊和登錄

微信與新浪微博都有 UnionID 登錄機制,使用 UnionID 注冊登錄,可以使得不同微信公眾號或小程序之間共享用戶。

+

 

微信的 authData 內容:

+

 

 "authData": { "access_token" : "access_token", "expires_in" : 7200, "openid" : "openid", "refresh_token" : "refresh_token", "scope" : "snsapi_userinfo", "unionid" : "ox7NLs-e-32ZyHg2URi_F2iPEI2U" }
 

使用 UnionID 注冊登錄,需要提供帶有 unionid 參數的 authData。另外需要配合傳遞 main_account 和 platform 這兩個字段。

+

 

  • main_account: main_account 為 true 表示使用 unionid 來登錄或者注冊。
  • platform:用來識別注冊平台,如新浪微博或微信等。

在服務端進行存儲的時候會根據 platform 來命名新增的平台,如傳入 "platform" = "weibo" 時,返回數據中會增加 _weibo_unionid 字段存儲 {"uid":"xxxxx"}

+

 

"_weibo_unionid": { "uid": "ox7NLs-e-32ZyHg2URi_F2iPEI2U" }
 

完整的第三方注冊登錄請求如下,以使用微信 UnionId 為例:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "authData": { "weixin1": { "openid": "oTY851cqL0gk3DqW3xINqG1Q4PTc", "access_token": "12_b6mz7ujXbTY4vpbqCRaKVa_y0Ij3N9grCeVtM8VJT8KFd4qnQ9lXtBsZVxG6x9c9Nay_oNgvbKK7KYKbn8R2P7uEgA0EhsXMHmxkx-xU-Tk", "expires_in": 7200, "refresh_token": "12_71UYUnqHDuIfekimsJsYjBDfY67ilo30fDqrYkqlwZtxNgcBhMmQgDVhT6mJWkRg0mngvX9kXeCGP8kmBWdvUtc5ngRiN5LDTWAau4du838", "scope": "snsapi_userinfo", "unionid": "ox7NLs-e-32ZyHg2URi_F2iPEI2U", "platform": "weixin", "main_account":"true" } } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/users

應答內容包括 objectId、createdAt、sessionToken、authData 以及一個自動生成的隨機 username,應答的 body 類似:

+

 

{ "sessionToken": "v53f0q4oecbrjojn530w89s5f", "updatedAt": "2018-08-16T08:03:44.203Z", "objectId": "5b752fe0a22b9d003137e16d", "username": "vp7szn9ytuaylgtnw14qnjx2u", "createdAt": "2018-08-16T08:03:44.203Z", "emailVerified": false, "authData": { "weixin1": { "openid": "oTY851cqL0gk3DqW3xINqG1Q4PTc", "access_token": "12_b6mz7ujXbTY4vpbqCRaKVa_y0Ij3N9grCeVtM8VJT8KFd4qnQ9lXtBsZVxG6x9c9Nay_oNgvbKK7KYKbn8R2P7uEgA0EhsXMHmxkx-xU-Tk", "expires_in": 7200, "refresh_token": "12_71UYUnqHDuIfekimsJsYjBDfY67ilo30fDqrYkqlwZtxNgcBhMmQgDVhT6mJWkRg0mngvX9kXeCGP8kmBWdvUtc5ngRiN5LDTWAau4du838", "scope": "snsapi_userinfo", "unionid": "ox7NLs-e-32ZyHg2URi_F2iPEI2U", "platform": "weixin", "main_account": "true" }, "_weixin_unionid": { "uid": "ox7NLs-e-32ZyHg2URi_F2iPEI2U" } }, "mobilePhoneVerified": false }
 

連接

連接一個現有的用戶到新浪微博或者微信,可以向 user endpoint 發送一個附帶 authData 字段的 PUT 請求來實現。例如,連接一個用戶到微信賬號發起的請求類似這樣:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "X-LC-Session: qmdj8pdidnmyzp0c7yqil91oc" \ -H "Content-Type: application/json" \ -d '{ "authData": { "weixin": { "uid": "123456789", "access_token": "2.00vs3XtCI5FevCff4981adb5jj1lXE", "expiration_in": "36000" ... } } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/users/55a47496e4b05001a7732c5f

完成連接后,你可以使用匹配的 authData 來認證他們。

+

 

斷開連接

斷開一個現有用戶到某個服務,可以通過刪除 authData 中對應的平台來做到。 例如,已經綁定過微信的用戶 authData 數據格式如下,平台名稱為 weixin

+

 

{ "username": "3td7p1nucap1i1p53m1zibwgx", "authData": { "weixin": { "openid": "oTY851cqL0gk3DqW3xINqG1Q4PTc", "scope": "snsapi_userinfo", "refresh_token": "refresh_token", "platform": "weixin", "unionid": "unionid, "access_token": "access_token", "expires_in": 7200 } }, }
 

取消微信關聯通過刪除 authData.weixin 來實現:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "X-LC-Session: 6fehqhr2t2na5mv1aq2om7jgz" \ -H "Content-Type: application/json" \ -d '{"authData.weixin":{"__op":"Delete"}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/users/5b7e53a767f356005fb374f6

其返回值類似於:

+

 

{ "updatedAt":"2018-08-23T06:32:47.633Z", "objectId":"5b7e53a767f356005fb374f6" }
 

安全

當你用 REST API key 來訪問 LeanCloud 時,訪問可能被 ACL 所限制,就像 iOS 和 Android SDK 上所做的一樣。你仍然可以通過 REST API 來讀和修改,只需要通過 ACL 的 key 來訪問一個對象。

+

 

ACL 按 JSON 對象格式來表示,JSON 對象的 key 是 objectId 或者一個特別的 key(*,表示公共訪問權限)。ACL 的值是權限對象,這個 JSON 對象的 key 即是權限名,而這些 key 的值總是 true。

+

 

舉個例子,如果你想讓一個 id 為 55a47496e4b05001a7732c5f 的用戶有讀和寫一個對象的權限,而且這個對象應該可以被公共讀取,符合的 ACL 應該是:

+

 

{ "55a47496e4b05001a7732c5f": { "read": true, "write": true }, "*": { "read": true } }
 

角色

當你的 app 的規模和用戶基數成長時,你可能發現你需要比 ACL 模型(針對每個用戶)更加粗粒度的訪問控制你的數據的方法。為了適應這種需求,LeanCloud 支持一種基於角色的權限控制方式。角色系統提供一種邏輯方法讓你通過權限的方式來訪問你的數據,角色是一種有名稱的對象,包含了用戶和其他角色。任何授予一個角色的權限隱含着授予它包含着的其他的角色相應的權限。

+

 

例如,在你的 app 中管理着一些內容,你可能有一些類似於「主持人」的角色可以修改和刪除其他用戶創建的新的內容,你可能還有一些「管理員」有着與「主持人」相同的權限,但是還可以修改 app 的其他全局性設置。通過給予用戶這些角色,你可以保證新的用戶可以做主持人或者管理員,不需要手動地授予每個資源的權限給各個用戶。

+

 

我們提供一個特殊的角色(Role)類來表示這些用戶組,為了設置權限用。角色有一些和其他對象不太一樣的特殊字段。

+

 

字段 說明
name 角色的名字,這個值是必須的,而且只允許被設置一次,只要這個角色被創建了的話。角色的名字必須由字母、空格、減號或者下划線這些字符構成。這個名字可以用來標明角色而不需要它的 objectId。
users 一個指向一系列用戶的關系,這些用戶會繼承角色的權限。
roles 一個指向一系列子角色的關系,這些子關系會繼承父角色所有的權限。

通常來說,為了保持這些角色安全,你的移動 app 不應該為角色的創建和管理負責。作為替代,角色應該是通過一個不同的網頁上的界面來管理,或者手工被管理員所管理。我們的 REST API 允許你不需要一個移動設備就能管理你的角色。

+

 

創建角色

創建一個新的角色與其他的對象不同的是 name 字段是必須的。角色必須指定一個 ACL,這個 ACL 必須盡量的約束嚴格一些,這樣可以防止錯誤的用戶修改角色。

+

 

創建一個新角色,發送一個 POST 請求到 roles 根路徑:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "name": "Manager", "ACL": { "*": { "read": true } } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/roles

其返回值類似於:

+

 

{ "createdAt":"2015-07-14T03:34:41.074Z", "objectId":"55a48351e4b05001a774a89f" }
 

你可以通過加入已有的對象到 roles 和 users 關系中來創建一個有子角色和用戶的角色:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "name": "CLevel", "ACL": { "*": { "read": true } }, "roles": { "__op": "AddRelation", "objects": [ { "__type": "Pointer", "className": "_Role", "objectId": "55a48351e4b05001a774a89f" } ] }, "users": { "__op": "AddRelation", "objects": [ { "__type": "Pointer", "className": "_User", "objectId": "55a47496e4b05001a7732c5f" } ] } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/roles

當創建成功時,HTTP 返回是 201 Created 而 Location header 包含了新的對象的 URL:

+

 

Status: 201 Created Location: https://{{appid 前八位}}.api.lncld.net/1.1/roles/55a483f0e4b05001a774b837
 

獲取角色

你可以同樣通過發送一個 GET 請求到 Location header 中返回的 URL 來獲取這個對象,比如我們想要獲取上面創建的對象:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/roles/55a483f0e4b05001a774b837

響應的 body 是一個 JSON 對象包含角色的所有字段:

+

 

{ "name":"CLevel", "createdAt":"2015-07-14T03:37:20.992Z", "updatedAt":"2015-07-14T03:37:20.994Z", "objectId":"55a483f0e4b05001a774b837", "users":{ "__type":"Relation", "className":"_User" }, "roles":{ "__type":"Relation", "className":"_Role" } }
 

注意 users 和 roles 關系無法在 JSON 中見到,你需要相應地用 $relatedTo 操作符來查詢角色中的子角色和用戶。

+

 

更新角色

更新一個角色通常可以像更新其他對象一樣使用,但是 name 字段是不可以更改的。加入和刪除 users 和 roles 可以通過使用AddRelation 和 RemoveRelation操作來進行。

+

 

舉例來說,我們對 Manager 角色加入 1 個用戶:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "users": { "__op": "AddRelation", "objects": [ { "__type": "Pointer", "className": "_User", "objectId": "55a4800fe4b05001a7745c41" } ] } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/roles/55a48351e4b05001a774a89f

相似的,我們可以刪除一個 Manager 的子角色:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "roles": { "__op": "RemoveRelation", "objects": [ { "__type": "Pointer", "className": "_Role", "objectId": "55a483f0e4b05001a774b837" } ] } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/roles/55a48351e4b05001a774a89f

刪除對象

為了從 LeanCloud 上刪除一個角色,只需要發送 DELETE 請求到它的 URL 就可以了。

+

 

我們需要傳入 X-LC-Session 來通過一個有權限的用戶賬號來訪問這個角色對象,例如:

+

 

curl -X DELETE \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "X-LC-Session: qmdj8pdidnmyzp0c7yqil91oc" \ https://{{appid 前八位}}.api.lncld.net/1.1/roles/55a483f0e4b05001a774b837

安全性

當你通過 REST API key 訪問 LeanCloud 的時候,訪問同樣可能被 ACL 所限制,就像 iOS 和 Android SDK 上一樣。你仍然可以通過 REST API 來讀和修改 ACL,只用通過訪問「ACL」鍵就可以了。

+

 

除了用戶級的權限設置以外,你可以通過設置角色級的權限來限制對 LeanCloud 對象的訪問。取代了指定一個 objectId 帶一個權限的方式,你可以設定一個角色的權限為它的名字在前面加上 role: 前綴作為 key。你可以同時使用用戶級的權限和角色級的權限來提供精細的用戶訪問控制。

+

 

比如,為了限制一個對象可以被在 Staff 里的任何人讀到,而且可以被它的創建者和任何有 Manager 角色的人所修改,你應該向下面這樣設置 ACL:

+

 

{ "55a4800fe4b05001a7745c41": { "write": true }, "role:Staff": { "read": true }, "role:Manager": { "write": true } }
 

你不必為創建的用戶和 Manager 指定讀的權限,如果這個用戶和 Manager 本身就是 Staff 的子角色和用戶,因為它們都會繼承授予 Staff 的權限。

+

 

角色繼承

就像上面所說的一樣,一個角色可以包含另一個,可以為 2 個角色建立一個「父子」關系。這個關系的結果就是任何被授予父角色的權限隱含地被授予子角色。

+

 

這樣的關系類型通常在用戶管理的內容類的 app 上比較常見,比如論壇。有一些少數的用戶是「管理員」,有最高級的權限來調整程序的設置、創建新的論壇、設定全局的消息等等。

+

 

另一類用戶是「版主」,他們有責任保證用戶生成的內容是合適的。任何有管理員權限的人都應該有版主的權利。為了建立這個關系,你應該把「Administartors」的角色設置為「Moderators」 的子角色,具體來說就是把 Administrators 這個角色加入 Moderators 對象的 roles 關系之中:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "roles": { "__op": "AddRelation", "objects": [ { "__type": "Pointer", "className": "_Role", "objectId": "<AdministratorsRoleObjectId>" } ] } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/roles/<ModeratorsRoleObjectId>

文件

對於文件上傳,我們推薦使用各個客戶端的 SDK 進行操作,或者使用命令行工具

+

 

通過 REST API 上傳文件受到三個限制:

+

 

  • 上傳最大文件大小有 10 M 的限制
  • 每個應用每秒最多上傳 1 個文件
  • 每個應用每分鍾最多上傳 30 個文件

而使用 SDK 或者命令行上傳沒有這些限制。

+

 

上傳文件

北美和華東節點不支持通過 REST API 上傳文件,請使用 SDK 提供的文件相關接口上傳文件。

+

 

上傳文件到 LeanCloud 通過 POST 請求,注意必須指定文件的 content-type,例如上傳一個文本文件 hello.txt 包含一行字符串:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: text/plain" \ -d 'Hello, World!' \ https://{{appid 前八位}}.api.lncld.net/1.1/files/hello.txt

文件上傳成功后,返回 201 Created 的應答和創建的文件對象(可以在 _File 表看到):

+

 

{ "size":13, "bucket":"1qdney6b", "url":"http://ac-1qdney6b.qiniudn.com/3zLG4o0d27MsCQ0qHGRg4JUKbaXU2fiE35HdhC8j.txt", "name":"hello.txt", "createdAt":"2014-10-14T05:55:57.455Z", "objectId":"543cbaede4b07db196f50f3c" }
 

其中 url 就是文件下載鏈接,objectId 是文件的對象 id,name 就是上傳的文件名稱。

+

 

也可以嘗試上傳一張圖片,假設當前目錄有一個文件 test.png:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: image/png" \ --data-binary '@test.png' \ https://{{appid 前八位}}.api.lncld.net/1.1/files/test.png

關聯文件到對象

一個文件上傳后,你可以關聯該文件到某個 AVObject 對象上:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "name": "hjiang", "picture": { "id": "543cbaede4b07db196f50f3c", "__type": "File" } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Staff

其中 id 就是文件對象的 objectId。

+

 

刪除文件

知道文件對象 ObjectId 的情況下,可以通過 DELETE 刪除文件:

+

 

curl -X DELETE \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/files/543cbaede4b07db196f50f3c

Push 通知

請查看我們的 消息推送開發指南 · 使用 REST API 推送消息

+

 

安裝數據

上傳安裝數據

一個安裝對象表示了一個你的在手機上被安裝的 app,這些對象被用來保存訂閱數據的,這些數據是一個或多個通知通道訂閱的。安裝數據除了一些特殊字段以外都可以是模式可變的。這些字段都有特殊的類型和驗證需求。

+

 

字段 描述
badge 數字,表示最新的 iOS 的安裝已知的 application badge。
channels 數組,可選,表示這個安裝對象的訂閱頻道列表設備訂閱的頻道。每個 channel 名稱只能包含 26 個英文字母和數字。
deviceToken 由 Apple 生成的字符串標志,在 deviceType 為 iOS 上的設備是必須的,而且自對象生成開始就不能改動,對於一個 app 來說也是不可重復的。
deviceType 必須被設置為 "ios"、"android"、"wp"、"web"中的一種,而且自這個對象生成以后就不能變化。
installationId 由 LeanCloud 生成的字符串標志,而且如果 deviceType 是 android 的話是一個必選字段,如果是 iOS 的話則可選。它只要對象被生成了就不能發生改變,而且對一個 app 來說是不可重復的。
timeZone 字符串,表示安裝的這個設備的系統時區。

大部分時間,安裝數據是被客戶端中有關 push 的方法所修改的。舉個例子,從客戶端 SDK 中調用 subscribeToChannel 或者 unsubscribeFromChannel,如果現在還沒有安裝對象的或者沒有更新安裝對象的話會創建一個對象,而從客戶端 SDK 中調用 getSubscribedChanneles 會從安裝對象中讀取訂閱數據。

+

 

REST 的方法可以被用來模仿這些操作。比如,如果你有一個 iOS 的 device token 你可以注冊它來向設備推送通知,只需要創建一個有需要的 channels 的安裝對象就可以了。你同樣可以做一些不能通過客戶端 SDK 進行的操作,就比如說查詢所有的安裝來找到一個 channel 的訂閱者的集合。

+

 

創建一個安裝對象和普通的對象差不多,但是特殊的幾個安裝字段必須通過認證。舉個例子,如果你有一個由 Apple Push Notification 提供的 device token,而且想訂閱一個廣播頻道,你可以如下發送請求:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "deviceType": "ios", "deviceToken": "abcdefghijklmnopqrstuvwzxyrandomuuidforyourdevice012345678988", "channels": [ "" ] }' \ https://{{appid 前八位}}.api.lncld.net/1.1/installations

當創建成功后,HTTP的返回值為 201 Created,Location header 包括了新的安裝的 URL:

+

 

Status: 201 Created Location: https://{{appid 前八位}}.api.lncld.net/1.1/installations/51ff1808e4b074ac5c34d7fd
 

返回的 body 是一個 JSON 對象,包括了 objectId 和 createdAt 這個創建對象的時間戳。

+

 

{ "createdAt": "2012-04-28T17:41:09.106Z", "objectId": "51ff1808e4b074ac5c34d7fd" }
 

獲取安裝對象

你可以通過 GET 方法請求創建的時候 Location 表示的 URL 來獲取 Installation 對象。比如,獲取上面的被創建的對象:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/installations/51ff1808e4b074ac5c34d7fd

返回的 JSON 對象所有用戶提供的字段,加上 createdAt、updatedAt 和 objectId 字段:

+

 

{ "deviceType": "ios", "deviceToken": "abcdefghijklmnopqrstuvwzxyrandomuuidforyourdevice012345678988", "channels": [ "" ], "createdAt": "2012-04-28T17:41:09.106Z", "updatedAt": "2012-04-28T17:41:09.106Z", "objectId": "51ff1808e4b074ac5c34d7fd" }
 

更新安裝對象

安裝對象可以向相應的 URL 發送 PUT 請求來更新。例如,為了讓設備訂閱一個名字為「foo」的推送頻道:

+

 

curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "deviceType": "ios", "deviceToken": "abcdefghijklmnopqrstuvwzxyrandomuuidforyourdevice012345678988", "channels": [ "", "foo" ] }' \ https://{{appid 前八位}}.api.lncld.net/1.1/installations/51ff1808e4b074ac5c34d7fd

查詢安裝對象

你可以一次通過 GET 請求到 installations 的根 URL 來獲取多個安裝對象。這項功能在 SDK 中不可用。

+

 

沒有任何 URL 參數的話,一個 GET 請求會列出所有安裝:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/installations

返回的 JSON 對象的 results 字段包含了所有的結果:

+

 

{ "results": [ { "deviceType": "ios", "deviceToken": "abcdefghijklmnopqrstuvwzxyrandomuuidforyourdevice012345678988", "channels": [ "" ], "createdAt": "2012-04-28T17:41:09.106Z", "updatedAt": "2012-04-28T17:41:09.106Z", "objectId": "51ff1808e4b074ac5c34d7fd" }, { "deviceType": "ios", "deviceToken": "876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9", "channels": [ "" ], "createdAt": "2012-04-30T01:52:57.975Z", "updatedAt": "2012-04-30T01:52:57.975Z", "objectId": "51fcb74ee4b074ac5c34cf85" } ] }
 

所有對普通的對象的查詢都對 installatin 對象起作用,所以可以查看之前的查詢部分以獲取詳細信息。通過做 channels 的數組查詢,你可以查找一個訂閱了給定的推送頻道的所有設備.

+

 

刪除安裝對象

為了從 AVOSCloud 中刪除一個安裝對象,可以發送 DELETE 請求到相應的 URL。這個功能在客戶端 SDK 也不可用。舉例:

+

 

curl -X DELETE \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/installations/51fcb74ee4b074ac5c34cf85

數據 Schema

為了方便開發者使用、自行研發一些代碼生成工具或者內部使用的管理平台。我們提供了獲取數據 Class Schema 的開放 API,基於安全考慮,強制要求使用 Master Key 才可以訪問。

+

 

查詢一個應用下面所有 Class 的 Schema:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ https://{{appid 前八位}}.api.lncld.net/1.1/schemas

返回的 JSON 數據包含了每個 Class 對應的 Schema:

+

 

{ "_User":{ "username" : {"type":"String"}, "password" : {"type":"String"}, "objectId" : {"type":"String"}, "emailVerified": {"type":"Boolean"}, "email" : {"type":"String"}, "createdAt" : {"type":"Date"}, "updatedAt" : {"type":"Date"}, "authData" : {"type":"Object"} } ……其他 class…… }
 

也可以單獨獲取某個 Class 的 Schema:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ https://{{appid 前八位}}.api.lncld.net/1.1/schemas/_User

雲函數

請查看我們的 雲引擎 REST API 使用指南

+

 

地理查詢

假如在發布微博的時候,我們也支持用戶加上當時的位置信息(新增一個 location 字段),如果想看看指定的地點附近發生的事情,可以通過 GeoPoint 數據類型加上在查詢中使用 $nearSphere 做到。獲取離當前用戶最近的 10 條微博應該看起來像下面這個樣子:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'limit=10' \ --data-urlencode 'where={ "location": { "$nearSphere": { "__type": "GeoPoint", "latitude": 39.9, "longitude": 116.4 } } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

這會按照距離緯度 39.9、經度 116.4(當前用戶所在位置)的遠近排序返回一系列結果,第一個就是最近的對象。(注意:如果指定了 order 參數的話,它會覆蓋按距離排序。)

+

 

為了限定搜索的最大距離,需要加入 $maxDistanceInMiles 和 $maxDistanceInKilometers或者 $maxDistanceInRadians 參數來限定。比如要找的半徑在 10 英里內的話:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={ "location": { "$nearSphere": { "__type": "GeoPoint", "latitude": 39.9, "longitude": 116.4 }, "$maxDistanceInMiles": 10.0 } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

同樣做查詢尋找在一個特定的范圍里面的對象也是可以的,為了找到在一個矩形的區域里的對象,按下面的格式加入一個約束 {"$within": {"$box": [southwestGeoPoint, northeastGeoPoint]}}

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'where={ "location": { "$within": { "$box": [ { "__type": "GeoPoint", "latitude": 39.97, "longitude": 116.33 }, { "__type": "GeoPoint", "latitude": 39.99, "longitude": 116.37 } ] } } }' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post

警告

這是有一些問題是值得留心的:

+

 

  1. 每一個 AVObject 類只能包含一個 AVGeoPoint 對象的鍵值。
  2. Points 不應該等於或者超出它的界. 緯度不應該是 -90.0 或者 90.0,經度不應該是 -180.0 或者 180.0。試圖在 GeoPoint 上使用超出范圍內的經度和緯度會導致問題.

用戶反饋組件 API

提交一條新的用戶反饋:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d '{ "status" : "open", "content" : "反饋的文字內容", "contact" : "聯系方式、QQ 或者郵箱手機等" }' \ https://{{appid 前八位}}.api.lncld.net/1.1/feedback

提交后的用戶反饋在可以在 控制台 >(選擇應用)> 組件 > 用戶反饋 里看到。

+

 

獲取所有的反饋:

+

 

curl -X GET \ -H "X-LC-Id:{{appid}}" \ -H "X-LC-Key:{{appkey}}" \ -H "Content-Type: application/json" \ https://{{appid 前八位}}.api.lncld.net/1.1/feedback

獲取一條反饋里面的信息:

+

 

curl -X GET \ -H "X-LC-Id:{{appid}}" \ -H "X-LC-Key:{{appkey}}" \ -H "Content-Type: application/json" \ https://{{appid 前八位}}.api.lncld.net/1.1/feedback/<:feedback_objectId>/threads

將 <:feedback_objectId> 替換為 feedback 的 objectId(可以從上述的「獲取所有的反饋」這個查詢中得到 objectId)。

+

 

客服為一條已經存在的反饋增加一條回復:

+

 

curl -X POST \ -H "X-LC-Id:{{appid}}" \ -H "X-LC-Key:{{appkey}}"\ -H "Content-Type: application/json" \ -d '{"type":"dev","content":"感謝您的反饋!我們正在修復您所述的問題,修復后再通知您。", "attachment":""}' \ https://{{appid 前八位}}.api.lncld.net/1.1/feedback/<:feedback_objectId>/threads

用戶為一條已經存在的反饋增加一條回復:

+

 

curl -X POST \ -H "X-LC-Id:{{appid}}" \ -H "X-LC-Key:{{appkey}}"\ -H "Content-Type: application/json" \ -d '{"type":"user","content":"我剛才又試了下,現在沒問題了!耶~", "attachment":""}' \ https://{{appid 前八位}}.api.lncld.net/1.1/feedback/<:feedback_objectId>/threads

短信驗證 API

請參考 短信服務 REST API 詳解

+

 

即時通訊 API

請參考 即時通訊 REST API

+

 

事件流 API

請參考 事件流 REST API

+

 

應用內搜索 API

請參考 搜索 API

+

 

數據導出 API

你可以通過請求 /exportData 來導出應用數據:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -H "Content-Type: application/json" \ -d '{}' \ https://{{appid 前八位}}.api.lncld.net/1.1/exportData

exportData 要求使用 master key 來授權。

+

 

你還可以指定導出數據的起始時間:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -H "Content-Type: application/json" \ -d '{"from_date":"2015-09-20", "to_date":"2015-09-25"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/exportData

還可以指定具體的 class 列表,使用逗號隔開:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -H "Content-Type: application/json" \ -d '{"classes":"_User,GameScore,Post"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/exportData

增加 only-schema 選項就可以只導出 schema:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -H "Content-Type: application/json" \ -d '{"only-schema":"true"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/exportData

導出的 Schema 文件同樣可以使用數據導入功能來導入到其他應用。

+

 

默認導出的結果將發送到應用的創建者郵箱,你也可以指定接收郵箱:

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -H "Content-Type: application/json" \ -d '{"email":"username@exmaple.com"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/exportData

調用結果將返回本次任務的 id 和狀態:

+

 

{ "status":"running", "id":"1wugzx81LvS5R4RHsuaeMPKlJqFMFyLwYDNcx6LvCc6MEzQ2", "app_id":"{{appid}}" }

除了被動等待郵件之外,你還可以主動使用 id 去查詢導出任務狀態:

+

 

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ https://{{appid 前八位}}.api.lncld.net/1.1/exportData/1wugzx81LvS5R4RHsuaeMPKlJqFMFyLwYDNcx6LvCc6MEzQ2

如果導出完成,將返回導出結果的下載鏈接:

+

 

{ "status":"done", "download_url": "https://download.leancloud.cn/export/example.tar.gz", "id":"1wugzx81LvS5R4RHsuaeMPKlJqFMFyLwYDNcx6LvCc6MEzQ2", "app_id":"{{appid}}" }

如果任務還沒有完成, status 仍然將為 running 狀態,請間隔一段時間后再嘗試查詢。

+

 

其他 API

服務器時間

獲取服務端當前日期時間可以通過 /date API:

+

 

curl -i -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ https://{{appid 前八位}}.api.lncld.net/1.1/date

返回 UTC 日期:

+

 

{ "iso": "2015-08-27T07:38:33.643Z", "__type": "Date" }
 

離線數據分析 API

該項功能僅向商業版和企業版應用開放。因此,開發版應用如果調用該 API 會收到錯誤響應。

+

 

創建分析 job API

離線數據分析 API 可以獲取一個應用的備份數據。因為應用數據的隱私敏感性,離線數據分析 API 必須使用 master key 的簽名方式鑒權,請參考 更安全的鑒權方式 一節。

+

 

創建分析 job。(注意:下面示例直接使用帶 master 標識的 X-LC-Key,不過我們推薦你在實際使用中采用 新鑒權方式 加密,不要明文傳遞 Key。)

+

 

curl -X POST \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -H "Content-Type: application/json" \ -d '{"jobConfig":{"sql":"select count(*) from table"}}' \ https://{{appid 前八位}}.api.lncld.net/1.1/bigquery/jobs

需要特別說明的是,jobConfig 不僅可以提供查詢分析 sql,還可以增加其他配置項:

+

 

  • 查詢結果自動另存為:
{ "jobConfig":{ "sql":"select count(*) as count from table", "saveAs":{ "className":"Table1", "limit":100 } } }
 
  • 設置依賴 job,也就是當前的查詢可以使用前趨查詢結果:
{ "jobConfig":{ "sql":"select * from table inner join tempTable on table.id=tempTable.objectId", "dependencyJobs":[ { "id":"xxx", "className":"tempTable" } // id 為依賴 job 的 jobId, className 則為自定義的臨時表名 ] } }
 

對應的輸出:

+

 

HTTP/1.1 200 OK Server Tengine is not blacklisted Server: Tengine Date: Fri, 05 Jun 2015 02:45:22 GMT Content-Type: application/json; charset=UTF-8 Content-Length: 100 Connection: keep-alive Strict-Transport-Security: max-age=31536000 {"id":"63f3b70b8ac3fd779de5bcb765cf121e","appId":"{{appid}}"}

獲取分析 job 結果 API

curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -H "Content-Type: application/json" \ https://{{appid 前八位}}.api.lncld.net/1.1/bigquery/jobs/:jobId

對應的輸出:

+

 

HTTP/1.1 200 OK Server Tengine is not blacklisted Server: Tengine Date: Fri, 05 Jun 2015 03:03:51 GMT Content-Type: application/json; charset=UTF-8 Content-Length: 127 Connection: keep-alive Strict-Transport-Security: max-age=31536000 {"id":"63f3b70b8ac3fd779de5bcb765cf121e","status":"OK","results":[{"_c0":6895}],"totalCount":1,"previewCount":1,"nextAnchor":1}
 

瀏覽器跨域和特殊方法解決方案

注:直接使用 RESTful API 遇到跨域問題,請遵守 HTML5 CORS 標准即可。以下方法非推薦方式,而是內部兼容方法。

+

 

對於跨域操作,我們定義了如下的 text/plain 數據格式來支持用 POST 的方法實現 GET、PUT、DELETE 的操作。

+

 

GET

 curl -i -X POST \ -H "Content-Type: text/plain" \ -d \ '{"_method":"GET", "_ApplicationId":"{{appid}}", "_ApplicationKey":"{{appkey}}"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

對應的輸出:

+

 

HTTP/1.1 200 OK Server: nginx Date: Thu, 04 Dec 2014 06:34:34 GMT Content-Type: application/json;charset=utf-8 Content-Length: 174 Connection: keep-alive Last-Modified: Thu, 04 Dec 2014 06:34:08.498 GMT Cache-Control: no-cache,no-store Pragma: no-cache Strict-Transport-Security: max-age=31536000 { "content": "每個 Java 程序員必備的 8 個開發工具", "pubUser": "LeanCloud官方客服", "pubTimestamp": 1435541999, "createdAt": "2015-06-29T01:39:35.931Z", "updatedAt": "2015-06-29T01:39:35.931Z", "objectId": "558e20cbe4b060308e3eb36c" }
 

PUT

curl -i -X POST \ -H "Content-Type: text/plain" \ -d \ '{"_method":"PUT", "_ApplicationId":"{{appid}}", "_ApplicationKey":"{{appkey}}", "upvotes":99}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

對應的輸出:

+

 

HTTP/1.1 200 OK Server: nginx Date: Thu, 04 Dec 2014 06:40:38 GMT Content-Type: application/json;charset=utf-8 Content-Length: 78 Connection: keep-alive Cache-Control: no-cache,no-store Pragma: no-cache Strict-Transport-Security: max-age=31536000 {"updatedAt":"2015-07-13T06:40:38.310Z","objectId":"558e20cbe4b060308e3eb36c"}
 

DELETE

curl -i -X POST \ -H "Content-Type: text/plain" \ -d \ '{"_method": "DELETE", "_ApplicationId":"{{appid}}", "_ApplicationKey":"{{appkey}}"}' \ https://{{appid 前八位}}.api.lncld.net/1.1/classes/Post/<objectId>

對應的輸出是:

+

 

HTTP/1.1 200 OK Server: nginx Date: Thu, 04 Dec 2014 06:15:10 GMT Content-Type: application/json;charset=utf-8 Content-Length: 2 Connection: keep-alive Cache-Control: no-cache,no-store Pragma: no-cache Strict-Transport-Security: max-age=31536000 {}
 

總之,就是利用 POST 傳遞的參數,把 _method、_ApplicationId 以及 _ApplicationKey 傳遞給服務端,服務端會自動把這些請求翻譯成指定的方法,這樣可以使得 Unity3D 以及 JavaScript 等平台(或者語言)可以繞開瀏覽器跨域或者方法限制。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM