鍵.png)
使用NestJS和Prisma構(gòu)建REST API:身份驗(yàn)證
在RESTful API中,每個(gè)資源都可以通過唯一的URL進(jìn)行標(biāo)識和訪問??蛻舳丝梢酝ㄟ^發(fā)送HTTP請求來執(zhí)行各種操作,如獲取資源、創(chuàng)建新資源、更新現(xiàn)有資源或刪除資源。RESTful API的設(shè)計(jì)遵循一些基本原則,如資源的表達(dá)、客戶端-服務(wù)器架構(gòu)、無狀態(tài)性和緩存等。REST API 支持本地 HTTP 緩存頭,并使用 HTTP 方法(POST、 GET、 PUT、 PATCH 和 DELETE)來操作數(shù)據(jù)。任何人都可以很容易地開始使用 REST,很簡單,而且學(xué)習(xí)曲線平滑。它還具有良好的可讀性和可維護(hù)性,因?yàn)槠涫褂脴?biāo)準(zhǔn)的HTTP方法和狀態(tài)碼來表示不同的操作結(jié)果。
然而,RESTful API也有一些限制。由于其無狀態(tài)性,每次請求都需要包含所有必要的信息,這可能會(huì)導(dǎo)致數(shù)據(jù)傳輸量較大。隨著應(yīng)用程序的擴(kuò)展,端點(diǎn)的數(shù)量急劇增加,更新數(shù)據(jù)庫模式或數(shù)據(jù)結(jié)構(gòu)也并不容易。此外,對于復(fù)雜的業(yè)務(wù)邏輯,RESTful API可能不夠靈活,需要額外的架構(gòu)和設(shè)計(jì)來滿足需求。
如果沒有任何特定的需求,REST 是最好的選擇。例如,如果是開發(fā)新手,那么使用 REST 是完美的匹配,因?yàn)樗膶W(xué)習(xí)曲線比較淺。此外,它還有一個(gè)很大的生態(tài)系統(tǒng),可以很容易地找到任何問題的解決方案。另外,在處理許多請求和有限的帶寬時(shí),最好使用 REST。在這種情況下,可以使用其緩存支持來提高性能。
GraphQL 是2015年引入的一種數(shù)據(jù)查詢語言。它允許開發(fā)人員精確定位并獲取他們需要的確切數(shù)據(jù)。與 REST 相比,GraphQL 是一種客戶端驅(qū)動(dòng)的方法,客戶端可以決定需要什么數(shù)據(jù)、如何獲取數(shù)據(jù)以及格式。它還解決了取得過多和取得不足的問題,因?yàn)榭蛻舳丝梢跃_定位所需的數(shù)據(jù)。
對于 API 而言,GraphQL 被視為一種新思路。GraphQL 既是一種用于 API 的查詢語言也是一個(gè)滿足你數(shù)據(jù)查詢的運(yùn)行時(shí)環(huán)境。GraphQL 對 API 中的數(shù)據(jù)提供了一套易于理解的完整描述,也讓 API 更容易地隨著時(shí)間推移而演進(jìn)。GitHub 是使用 GraphQL 的最大公司之一。2016年,GitHub 從 REST 轉(zhuǎn)向 GraphQL,極大地促進(jìn)了 GitHub 的快速增長。關(guān)于 GraphQL 的介紹,網(wǎng)上已經(jīng)有非常多的資料了,這里不再過多描述,具體可以參考 GraphQL.org。
在 GraphQL 中,類型系統(tǒng)用于描述 GraphQL Server 的能力并用于判斷一個(gè)查詢是否有效。類型系統(tǒng)還描述了查詢參數(shù)的輸入類型,并在 GraphQL Runtime 中檢查參數(shù)值的有效性。一個(gè) GraphQL 服務(wù)是通過定義類型和類型上的字段來創(chuàng)建的,然后給每個(gè)類型上的每個(gè)字段提供解析函數(shù)。例如,在 Github GraphQL Server 中,使用viewer字段來描述當(dāng)前登錄用戶的信息,而viewer的類型為User。一旦啟動(dòng)某個(gè) GraphQL Server,它就能接受 GraphQL 查詢,并驗(yàn)證和執(zhí)行該查詢。GraphQL Server 首先會(huì)檢查該查詢以確保它只引用了已定義的類型和字段,然后運(yùn)行指定的解析函數(shù)來生成結(jié)果。
與使用普通的 REST API 相比,強(qiáng)類型系統(tǒng)是 GraphQL 最吸引人的地方之一。GraphQL類型系統(tǒng)是其根基,所有人必須遵守,這就在大家對API接口描述形成統(tǒng)一認(rèn)識上發(fā)揮著重要作用。在 GraphQL 中,GraphQL Runtime 確定 GraphQL Server 可以提供的能力,而消費(fèi)端具體要獲取哪些數(shù)據(jù)則完全由消費(fèi)者說了算。客戶端(消費(fèi)端)可以以更加平等的地位,更加積極地參與到整個(gè)的數(shù)據(jù)交互過程。借助于GraphQL的類型系統(tǒng),客戶端可以更加自由地根據(jù)自己的需求來獲得自己的所需,而無需受到 Server 端的限制。
GraphQL 不但改變了通信雙方的話語權(quán),還使得客戶端可以精確地預(yù)測服務(wù)端的響應(yīng)。對于 API 的版本控制而言,GraphQL 借鑒了其他語言中的 @deprecated注解。
GraphQL的不足之處在于查詢可能很復(fù)雜,缺乏內(nèi)置的緩存支持。與 REST 相比,學(xué)習(xí) GraphQL 具有一定挑戰(zhàn)性,并且默認(rèn)情況下它不支持文件上傳。
即便如此,在確定是否要使用 GraphQL 技術(shù)時(shí),仍需要做認(rèn)真的分析,且不可為了追新而采用 GraphQL。GraphQL 是查詢具有多條記錄的數(shù)據(jù)庫的極佳選擇。您可以使用 GraphQL 消除數(shù)據(jù)的額外讀取,并且只檢索特定格式的必要數(shù)據(jù)以提高應(yīng)用程序性能。此外,GraphQL 非常適合于需要從多個(gè)資源聚合數(shù)據(jù)的情況。當(dāng)不完全理解客戶端如何使用 API 時(shí),也可以使用 GraphQL。使用 GraphQL,不需要事先定義一個(gè)嚴(yán)格的契約。相反,可以根據(jù)客戶端反饋逐步構(gòu)建 API。
gRPC 是 Google 在2016年引入的開源遠(yuǎn)程過程調(diào)用(RPC)框架,使用 Protocol Buffers(protobuf)作為接口描述語言。它是一個(gè)輕量級的解決方案,并使用最少的資源提供最大的性能。
gRPC 遵循基于契約的通信方法。它要求客戶機(jī)和服務(wù)器在開始通信之前都要有契約。GRPC 使用 Protobuf (一種聲明性語言)創(chuàng)建契約,它使用選定的語言為客戶機(jī)和服務(wù)器生成兼容的代碼。gRPC 提供了多語言的支持,包括但不限于C++, Java, Python, Go, Node.js等。這使得開發(fā)者可以在不同的語言中構(gòu)建相互兼容的服務(wù)和客戶端。
gRPC 支持4種通信方式:
gRPC 使用 HTTP/2 作為底層傳輸協(xié)議,帶來了更高的性能和效率。HTTP/2 支持多路復(fù)用、頭部壓縮和二進(jìn)制傳輸?shù)忍匦?,提高了通信的速度和資源利用率。它以二進(jìn)制格式序列化數(shù)據(jù),支持全雙工通信,還能夠進(jìn)行負(fù)載平衡。gRPC 擁有豐富的生態(tài)系統(tǒng),包括支持各種語言的庫和工具。它還與 Kubernetes、Envoy、Istio等流行的開源項(xiàng)目集成,提供更全面的解決方案。gRPC
總體而言,gRPC 是一個(gè)強(qiáng)大而高效的 RPC 框架,適用于構(gòu)建分布式系統(tǒng)、微服務(wù)架構(gòu)和支持實(shí)時(shí)通信的應(yīng)用程序。其設(shè)計(jì)理念注重性能、可擴(kuò)展性和跨語言支持,使得它在現(xiàn)代應(yīng)用開發(fā)中得到廣泛應(yīng)用。
Webhook是一種強(qiáng)大的技術(shù),它可以實(shí)現(xiàn)系統(tǒng)之間的即時(shí)更新和通知。通過使用HTTP回調(diào)機(jī)制,Webhook能夠確保各個(gè)系統(tǒng)之間的數(shù)據(jù)保持同步。
使用 Webhooks 時(shí),一個(gè)應(yīng)用程序(服務(wù)提供者)通常會(huì)提供一個(gè)注冊接口,讓另一個(gè)應(yīng)用程序(服務(wù)消費(fèi)者)注冊感興趣的事件。注冊成功后,服務(wù)提供者將在相關(guān)事件發(fā)生時(shí)向服務(wù)消費(fèi)者提供的回調(diào)地址發(fā)送 HTTP 請求,以觸發(fā)相應(yīng)的動(dòng)作。
Webhook的工作原理很簡單。當(dāng)某個(gè)事件發(fā)生時(shí),例如用戶提交表單、發(fā)布新的文章或更新數(shù)據(jù)庫,服務(wù)器會(huì)向預(yù)先定義的URL發(fā)送一個(gè)HTTP POST請求。這個(gè)URL可以是第三方應(yīng)用程序的API端點(diǎn),也可以是自己搭建的服務(wù)器。在接收到請求后,服務(wù)器會(huì)執(zhí)行相應(yīng)的邏輯,并將結(jié)果通過HTTP響應(yīng)返回給調(diào)用方。
通過這種方式,Webhook實(shí)現(xiàn)了系統(tǒng)之間的實(shí)時(shí)通信和數(shù)據(jù)同步。它消除了輪詢和定期請求的需求,減少了網(wǎng)絡(luò)流量和延遲。同時(shí),Webhook還具有高度的可擴(kuò)展性和靈活性,可以適應(yīng)各種不同的應(yīng)用場景。無論是開發(fā)電子商務(wù)網(wǎng)站、社交應(yīng)用還是物聯(lián)網(wǎng)設(shè)備,Webhook都是一個(gè)非常有用的工具。
SSE是一種基于HTTP的通信協(xié)議,它允許服務(wù)器向客戶端推送實(shí)時(shí)更新的數(shù)據(jù)。與傳統(tǒng)的輪詢或長輪詢不同,SSE通過建立持久的連接來實(shí)現(xiàn)數(shù)據(jù)的雙向通信。一旦連接建立,服務(wù)器就可以通過該連接將數(shù)據(jù)推送到客戶端,而無需客戶端再次發(fā)起請求。例如,客戶端首先發(fā)送一個(gè)HTTP GET請求到服務(wù)器,以建立持久的連接。然后,服務(wù)器會(huì)保持該連接打開,并隨時(shí)將新的數(shù)據(jù)推送到客戶端??蛻舳丝梢酝ㄟ^解析服務(wù)器發(fā)送的事件流來實(shí)時(shí)顯示或處理這些數(shù)據(jù)。對基于Web的應(yīng)用而言, 瀏覽器對SSE的支持如下:
由于SSE是基于HTTP協(xié)議的,因此它可以與各種編程語言和平臺兼容。無論是JavaScript、Python還是Java,都可以通過相應(yīng)的庫或框架來使用SSE。此外,SSE還具有良好的可擴(kuò)展性和性能優(yōu)勢,適用于處理大量的實(shí)時(shí)數(shù)據(jù)更新。
使用Server-Sent Events (SSE),可以體驗(yàn)到實(shí)時(shí)數(shù)據(jù)更新的便捷性,這種輕量級協(xié)議非常適合用于傳輸動(dòng)態(tài)內(nèi)容和即時(shí)信息。無論是開發(fā)實(shí)時(shí)聊天應(yīng)用、新聞聚合網(wǎng)站還是監(jiān)控儀表盤,SSE都是一個(gè)非常有用的工具。
???????????????????? ???????? ?????????????????????? (??????) 是一個(gè)用于交換商業(yè)文檔的標(biāo)準(zhǔn)。它通過規(guī)范文檔的結(jié)構(gòu)和內(nèi)容,使得不同系統(tǒng)之間能夠更順暢地交換業(yè)務(wù)信息, 也就是說,規(guī)范了API 通信內(nèi)容的格式。通過使用??????標(biāo)準(zhǔn),企業(yè)可以簡化業(yè)務(wù)流程,提高自動(dòng)化程度,并降低交易成本。
EDI可以通過API來實(shí)現(xiàn)互操作性。EDI將企業(yè)間的商業(yè)文檔轉(zhuǎn)換為標(biāo)準(zhǔn)的數(shù)據(jù)格式,這些數(shù)據(jù)格式轉(zhuǎn)換為其他應(yīng)用程序所需的數(shù)據(jù)格式。EDI可以將企業(yè)間的商業(yè)文檔與企業(yè)內(nèi)部的數(shù)據(jù)進(jìn)行集成,而API可以將不同應(yīng)用程序之間的數(shù)據(jù)進(jìn)行集成,從而實(shí)現(xiàn)數(shù)據(jù)的共享和流通。EDI可以自動(dòng)處理商業(yè)文檔,通過API可以自動(dòng)處理應(yīng)用程序之間的數(shù)據(jù)交換和通信,從而實(shí)現(xiàn)業(yè)務(wù)流程的自動(dòng)化。
對信息安全而言,EDI可以使用加密和數(shù)字證書等安全措施,而API可以使用訪問控制和身份驗(yàn)證等安全措施,從而保障信息的安全性。同時(shí)I可以通過數(shù)據(jù)分析來實(shí)現(xiàn)數(shù)據(jù)的挖掘和分析。EDI可以將企業(yè)間的商業(yè)文檔進(jìn)行匯總和分析,并且以API將不同應(yīng)用程序之間的數(shù)據(jù)進(jìn)行匯總和分析,從而實(shí)現(xiàn)數(shù)據(jù)的挖掘和分析。
“Event-Driven Architecture (EDA)” 指的是事件驅(qū)動(dòng)架構(gòu),在API的領(lǐng)域中,表示為API而設(shè)計(jì)的事件驅(qū)動(dòng)架構(gòu)。
事件驅(qū)動(dòng)架構(gòu)強(qiáng)調(diào)系統(tǒng)中各個(gè)組件之間通過事件進(jìn)行通信和協(xié)作。在這種架構(gòu)中,組件可以是獨(dú)立的服務(wù)、模塊、或者整個(gè)系統(tǒng)。事件是系統(tǒng)中發(fā)生的事情,可能是狀態(tài)變化、用戶動(dòng)作、外部觸發(fā)等。當(dāng)事件發(fā)生時(shí),系統(tǒng)中的組件可以發(fā)布(或廣播)該事件,同時(shí)對該事件感興趣的其他組件可以訂閱這些事件并做出響應(yīng)。
Event-Driven Architecture 將事件驅(qū)動(dòng)的思想應(yīng)用于API設(shè)計(jì)和交互。這種架構(gòu)風(fēng)格在處理異步、分布式、和實(shí)時(shí)性要求較高的應(yīng)用中非常有用。這一架構(gòu)強(qiáng)調(diào)了通過事件的發(fā)布和訂閱機(jī)制實(shí)現(xiàn) API 組件之間的松散耦合。API 組件可以是生產(chǎn)者(發(fā)布事件的組件)或消費(fèi)者(訂閱并響應(yīng)事件的組件)。DA使得 API 的通信變得異步化,允許組件在不直接等待響應(yīng)的情況下繼續(xù)執(zhí)行。這有助于提高系統(tǒng)的性能和可伸縮性。
事件驅(qū)動(dòng)的架構(gòu)適用于需要實(shí)時(shí)性響應(yīng)的場景,例如實(shí)時(shí)數(shù)據(jù)更新、通知推送等。通過事件分發(fā)機(jī)制,系統(tǒng)可以更即時(shí)地響應(yīng)發(fā)生的變化。事件驅(qū)動(dòng)的特性有助于微服務(wù)之間的通信和協(xié)作。一般地,API 網(wǎng)關(guān)可以充當(dāng)事件的分發(fā)者,負(fù)責(zé)將事件發(fā)送到相應(yīng)的訂閱者。這有助于集中管理事件的流向和處理。通過使用事件來驅(qū)動(dòng) API 的交互,系統(tǒng)能夠更好地適應(yīng)動(dòng)態(tài)變化和不同組件之間的異步通信需求。
WebSocket 實(shí)現(xiàn)了客戶端和服務(wù)器之間的雙向通信,為雙方提供了一種實(shí)時(shí)而高效的交互方式。通過 WebSocket,客戶端和服務(wù)器之間可以建立持久性的連接,使得雙方可以在任何時(shí)候都能夠發(fā)送和接收數(shù)據(jù)。這種雙向通信機(jī)制極大地拓展了傳統(tǒng)的請求-響應(yīng)模型,為開發(fā)者提供了更靈活、更即時(shí)的交互手段。
WebSocket 協(xié)議通過在客戶端和服務(wù)器之間創(chuàng)建一個(gè)持久性連接,允許雙方通過單個(gè)socket進(jìn)行實(shí)時(shí)通信。與傳統(tǒng)的 HTTP 請求-響應(yīng)模型不同,WebSocket 不需要在每次通信時(shí)都建立新的連接,從而減少了通信的開銷和延遲。這對于實(shí)時(shí)應(yīng)用程序、在線游戲、聊天應(yīng)用等場景非常有益。
在 WebSocket 中,客戶端和服務(wù)器之間的通信基于事件。一旦連接建立,任何一方都可以異步地發(fā)送消息給對方,而對方也能夠立即接收并響應(yīng)。這種實(shí)時(shí)的雙向通信機(jī)制極大地提高了應(yīng)用程序的交互性,使得用戶能夠在無感知延遲的情況下享受到更加流暢的應(yīng)用體驗(yàn)。
總體而言,WebSocket 的引入使得 Web 應(yīng)用程序在處理實(shí)時(shí)數(shù)據(jù)、推送通知和建立互動(dòng)性方面取得了顯著的進(jìn)步。通過 WebSocket,客戶端和服務(wù)器之間的雙向通信成為現(xiàn)代 Web 應(yīng)用中不可或缺的一部分,為開發(fā)者提供了更多創(chuàng)造性和實(shí)時(shí)性的可能性。
SOAP 是 Web 服務(wù)的通信協(xié)議, 定義了 Web service 消息的格式。SOAP 編碼用于告知 SOAP 運(yùn)行時(shí)環(huán)境如何從 Java 等數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化為 SOAP XML。
XML的可讀性和可擴(kuò)展性使得SOAP能夠靈活地適應(yīng)不同的應(yīng)用場景,常見的 Web 服務(wù)規(guī)范包括:
SOAP 是協(xié)議獨(dú)立的,可以在各種網(wǎng)絡(luò)協(xié)議上運(yùn)行,如HTTP、SMTP等。最常見的是在HTTP上使用SOAP,將SOAP消息封裝在HTTP協(xié)議中進(jìn)行傳輸。SOAP 和 WSDL 指示 Web 服務(wù)及其客戶端之間的通信。SOAP支持多種消息交互模式,包括單向消息、請求-響應(yīng)模式和異步消息。這使得它適用于不同的應(yīng)用場景,從簡單的數(shù)據(jù)查詢到復(fù)雜的業(yè)務(wù)流程。
SOAP消息的傳輸可以使用安全協(xié)議,如HTTPS,以確保在網(wǎng)絡(luò)上傳輸時(shí)的機(jī)密性和完整性。此外,SOAP還可以與其他安全標(biāo)準(zhǔn)(如WS-Security)結(jié)合使用,提供更高級的安全性支持。
MQTT 是一種輕量級的、開放的消息隊(duì)列傳輸協(xié)議,設(shè)計(jì)用于在低帶寬、高延遲或不穩(wěn)定網(wǎng)絡(luò)環(huán)境中進(jìn)行設(shè)備間通信。其設(shè)計(jì)注重資源效率,使其成為在受限環(huán)境中運(yùn)行的設(shè)備和應(yīng)用程序的理想選擇。其協(xié)議頭部較小,通信開銷較小,適用于嵌入式系統(tǒng)和移動(dòng)設(shè)備。
“ MQTT”中的“ MQ”是從 IBM 的 MQ (當(dāng)時(shí)稱為 MQSeries)產(chǎn)品線派生出來的,其中 MQ 代表“消息隊(duì)列”。然而,盡管名稱如此,該協(xié)議并不使用消息隊(duì)列; 相反,它提供發(fā)布-訂閱消息: 設(shè)備在特定主題上發(fā)布消息,所有訂閱該主題的設(shè)備都接收該消息。它的主要應(yīng)用包括向控制輸出發(fā)送消息,以及從傳感器節(jié)點(diǎn)讀取和發(fā)布數(shù)據(jù)。
MQTT 提供不同的服務(wù)質(zhì)量(Quality of Service,QoS)級別,以滿足不同應(yīng)用場景的需求。QoS級別包括至多一次(At most once)、至少一次(At least once)和只有一次(Exactly once)。
MQTT 支持持久性會(huì)話。客戶端可以選擇創(chuàng)建持久性會(huì)話,使得在客戶端斷開連接后,服務(wù)器能夠保留其訂閱信息。這有助于確??蛻舳嗽谥匦逻B接時(shí)能夠接收到之前錯(cuò)過的消息。
MQTT 支持基本的身份驗(yàn)證和傳輸層安全性,但通常需要與其他安全機(jī)制結(jié)合使用,例如TLS/SSL。
總之,MQTT 是一種靈活、輕量級且易于實(shí)現(xiàn)的可靠而高效協(xié)議,特別適用于需要實(shí)時(shí)、可靠通信的物聯(lián)網(wǎng)和嵌入式系統(tǒng)。如果希望對物聯(lián)網(wǎng)通信協(xié)議有更多的了解,可以參閱筆者的拙作——《一書讀懂物聯(lián)網(wǎng)》。
文章轉(zhuǎn)自微信公眾號@喔家ArchiSelf