社區開放一小步:Matters API

三月網站改版時,我們對技術架構進行了調整,其中前後端通信的 API 從 REST 改為 GraphQL。在經過幾個月的產品迭代、開放註冊帶來的流量攀升考驗後,
Matters API 正式對社區開放!
為什麼選擇 GraphQL?
雖然 GraphQL 與 REST 都能透過 HTTP 進行前後端的通信,但有幾個主要差異點:
請求(request):REST 使用 HTTP verbs (POST, PUT, GET, DELETE 等) 對資源進行操作,而 GraphQL 只有 query 和 mutation 兩種操作,且都可通過 POST 進行。
資源(resource):REST 用不同的 URI/endpoint 代表不同的資源,如 /users 為用戶, /articles 為文章,而 GraphQL 只有一個 URI/endpoint(通常為 /graphql),server 根據 client 需要返回相應的資源。
緩存(caching):市面上流行的 GraphQL 工具(如 Apollo)都默認將 query 操作用 POST 非 GET 發出請求,而 REST 則可利用 HTTP 的緩存機制,對 Network Caching(CDN)和 Client Caching(瀏覽器)都更為友好。
錯誤處理(error handling):REST 可利用 HTTP Status Code,配合 response body 返回錯誤響應,而 GraphQL 則返回 200 OK,需從 response body 解析。
可以看到,相比 GraphQL,REST 與 HTTP、URI 等 Web 技術有更強的耦合。產品開發時,資源導向(ROA)的 REST 在前後端協助時為後端驅動(server-driven),後端決定前端從哪裡獲取數據、能獲取什麼數據。這在過去十幾年裡已事實上成為 Web API 的標準,植根於 Web 的 REST ,也反哺於 Web 生態。

但隨著移動互聯網、物聯網的崛起,多平台應用、快速迭代的產品開發模式下,GraphQL 顯然更為合適。GraphQL 位於中間層,用約定的 schema 保證前後端的一致性,也讓不同平台各取所需,而日趨成熟的前端技術,也能接受更多來自後端的權力下放。

如何使用 Matters API?
在使用 Matters API 前,可先對 GraphQL 有基本的了解。當然,你也可通過下文動手實作來快速了解 GraphQL 和 Matters API。
Endpoints
Matters API 只有單一 endpoint:
https://server.matters.news/graphql
你可使用 Apollo Client、Relay 等框架進行前端開發,但為了方便上手,亦可通過 Playground 調用 Matters API:
https://server.matters.news/playground

API 文檔
點擊 Playground 右側欄「DOCS」,即可查看 Matters API 的文檔:

Queries 部分,我們把 viewer
設計為主入口,用於查詢當前訪客(User 對象,下圖)的相關數據,如 viewer.recommendation.hottest
對應 matters.news 的「熱門作品」;而次入口 article 則可通過 mediaHash
查詢 Article 對象(下例)。

Mutations 部分,則包含了登入(userLogin
)、發佈文章(publishArticle
)、追蹤作者(followUser
)等操作。
而 Subscriptions 部分,則可通過 nodeEdited
訂閱某個對象的實時更新。
文檔沒看明白?沒關係,我們一起通過實作來快速上手!
查詢 Query
在左側代碼編輯面板輸入 GraphQL 查詢語句,比如要獲取作品《按下一個讚,一起讓好內容活下去 | Matters和LikeCoin的合作正式上線!》 [1] 的標題和摘要:
query { article( input: { mediaHash: "zdpuAxP6uSfum74VS3pYmzBR9xvPbrBcX3J8BPpB3xdRGjVsX" } ) { id title summary } }
然後點擊中間「▶️」按鈕發出請求,即可於右側面板看到 API 返回的數據:

當然,也可通過點擊頂部右側的「COPY CURL」獲取 cURL 命令,在命令行工具中請求:
curl 'https://server.matters.news/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: https://server.matters.news' --data-binary '{"query":"\nquery {\n article(\n input: { mediaHash: \"zdpuAxP6uSfum74VS3pYmzBR9xvPbrBcX3J8BPpB3xdRGjVsX\" }\n ) {\n id\n title\n summary\n }\n}"}' --compressed
變更 Mutation
剛剛例子中,我們用匿名身份進行查詢,但如果要查看自己的收藏列表、發布作品、評論等等,都需登入後才可進行。如要收藏上例作品:
1. 登入以獲取 access token:
mutation { userLogin(input: { email: "test@example.com", password: "12345678" }) { token } }
(還沒有帳號?可先通過 sendVerificationCode
, confirmVerificationCode
和 registerUser
mutations 進行註冊。)
2. 在 Playground 左下角 HTTP HEADER 裡填上 x-access-token
,此後的請求都將以該登入用戶的身份進行:

3. 收藏作品
mutation { subscribeArticle(input: { id: "QXJ0aWNsZToxMDc4Mg" }) { id subscribed } }

在網站查看作品是否「已收藏」:

訂閱 Subscription
目前 Matters API 支持訂閱文章(Article 對象),每當文章有新評論、讚賞,都會實時通知你。
比如要實時接收某篇文章的新評論更新:
subscription { nodeEdited(input: { id: "QXJ0aWNsZToxMDc4Mg" }) { id ... on Article { id comments(input: { first: 1 }) { edges { node { id content } } } } } }
What’s Next?
在開放 API 前,已有社區用戶通過逆向工程做了一些小項目,@Vibert Thio 和 @Andy 寫了 Matters 第三方網站 和 App,@2049bbs 和 @Deserve 實現了工具讓你獲取文章的 IPFS 地址 ,方便牆內分享……,如果你有奇思妙想、實作了有趣的東西、使用 API 中遇到問題、發現 bug,歡迎發文分享、留言討論。
Matters API 只是社區開放的一小步,分布式的桌面版本、 matters.news 網站開源、Matters OAuth 都將在合適的時間節點向社區開放,歡迎大家和 Matters 一起探索!
創作有價,
Happy Coding ❤️
[1] matters.news 的作品 URL Pattern 為 :
https://matters.news/@${username}/${slug}-${mediaHash}
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!







- 来自作者