CherryPy - Web 服務

Web 服務是一組基於 Web 的元件,有助於在應用程式或系統之間交換資料,其中還包括開放協議和標準。它可以在網上釋出,使用和發現。

Web 服務有各種型別,如 RWS(RESTfUL Web 服務),WSDL,SOAP 等等。

REST - Representational State Transfer

一種遠端訪問協議,它將狀態從客戶端傳輸到伺服器,可用於操作狀態而不是呼叫遠端過程。

  • 沒有定義任何特定的編碼或結構以及返回有用錯誤訊息的方法。

  • 使用 HTTP 動作來執行狀態轉移操作。

  • 使用 URL 唯一標識資源。

  • 它不是 API,而是 API 傳輸層。

REST 維護網路上資源的命名,並提供統一的機制來對這些資源執行操作。每個資源由至少一個識別符號標識。如果 REST 基礎結構是以 HTTP 為基礎實現的,則這些識別符號稱為統一資源識別符號(URI)

以下是 URI 集的兩個常見子集 -

子集 完整形式 例子
URL 統一資源定位器 http://www.gmail.com/
URN 統一資源名稱 urn:isbn:0-201-71088-9 urn:uuid:13e8cf26-2a25-11db-8693-000ae4ea7d46

在瞭解 CherryPy 架構的實現之前,讓我們關注 CherryPy 的架構。

CherryPy 包括以下三個元件 -

  • cherrypy.engine - 它控制程序啟動/拆卸和事件處理。

  • cherrypy.server - 它配置和控制 WSGI 或 HTTP 伺服器。

  • cherrypy.tools - 與處理 HTTP 請求正交的實用工具箱。

REST 介面通過 CherryPy

RESTful Web 服務在以下幫助下實現 CherryPy 架構的每個部分 -

  • 認證
  • 授權
  • 結構體
  • 封裝
  • 錯誤處理

認證

身份驗證有助於驗證與我們互動的使用者。CherryPy 包含處理每種身份驗證方法的工具。

def authenticate():
   if not hasattr(cherrypy.request, 'user') or cherrypy.request.user is None:
      # < Do stuff to look up your users >
        
      cherrypy.request.authorized = False # This only authenticates. 
         Authz must be handled separately.
        
      cherrypy.request.unauthorized_reasons = []
      cherrypy.request.authorization_queries = []
        
cherrypy.tools.authenticate = \
   cherrypy.Tool('before_handler', authenticate, priority=10)

上述函式 authenticate() 將有助於驗證客戶端或使用者的存在。內建工具有助於系統地完成該過程。

授權

授權有助於通過 URI 維護流程的健全性。該過程還有助於通過使用者令牌引線變形物件。

def authorize_all():
   cherrypy.request.authorized = 'authorize_all'
    
cherrypy.tools.authorize_all = cherrypy.Tool('before_handler', authorize_all, priority=11)

def is_authorized():
   if not cherrypy.request.authorized:
      raise cherrypy.HTTPError("403 Forbidden",
         ','.join(cherrypy.request.unauthorized_reasons))
            
cherrypy.tools.is_authorized = cherrypy.Tool('before_handler', is_authorized, 
priority = 49)

cherrypy.config.update({
   'tools.is_authorized.on': True,
   'tools.authorize_all.on': True
})

內建的授權工具有助於系統地處理例程,如前面的示例所述。

結構體

維護 API 結構有助於減少對映應用程式 URI 的工作量。始終需要保持 API 可被發現和清潔。CherryPy 框架的 API 的基本結構應該如下 -

  • 帳戶和使用者
  • 自動應答
  • 聯絡
  • 檔案
  • 列表和欄位
  • 訊息和批處理

封裝

封裝有助於建立輕量級,人類可讀且可供各種客戶端訪問的 API。專案列表以及建立,檢索,更新和刪除需要封裝 API。

錯誤處理

如果 API 無法以特定的本能執行,此過程將管理錯誤(如果有)。例如,400 表示錯誤請求,403 表示未授權請求。

請考慮以下內容作為資料庫,驗證或應用程式錯誤的示例。

import cherrypy
import json

def error_page_default(status, message, traceback, version):
   ret = {
      'status': status,
      'version': version,
      'message': [message],
      'traceback': traceback
   }
    
   return json.dumps(ret)
    
class Root:
   _cp_config = {'error_page.default': error_page_default}
    
@cherrypy.expose
   def index(self):
      raise cherrypy.HTTPError(500, "Internal Sever Error")
cherrypy.quickstart(Root())

上面的程式碼將產生以下輸出 -

錯誤處理

由於內建的訪問工具,通過 CherryPy 可以輕鬆管理 API(應用程式程式設計介面)。

HTTP 方法

對資源進行操作的 HTTP 方法列表如下 -

原子釋出協議(Atom Publishing Protocol - APP)

APP 已經從 Atom 社群出現,作為 HTTP 之上的應用程式級協議,允許釋出和編輯 Web 資源。APP 伺服器和客戶端之間的訊息單元基於 Atom XML 文件格式。

Atom 釋出協議使用 HTTP 及其機制和 Atom XML 文件格式作為訊息單元,定義 APP 服務和使用者代理之間的一組操作。

APP 首先定義服務文件,該服務文件向使用者代理提供 APP 服務所服務的不同集合的 URI。

讓我們舉個例子來說明 APP 的工作原理 -

<?xml version = "1.0" encoding = "UTF-8"?>
<service xmlns = "http://purl.org/atom/app#" xmlns:atom = "http://www.w3.org/2005/Atom">
   
   <workspace>
      <collection href = "http://host/service/atompub/album/">
         <atom:title> Albums</atom:title>
         <categories fixed = "yes">
            <atom:category term = "friends" />
         </categories>
      </collection>
      
      <collection href = "http://host/service/atompub/film/">
         <atom:title>Films</atom:title>
         <accept>image/png,image/jpeg</accept>
      </collection>
   </workspace>
    
</service>

APP 指定如何使用 HTTP 方法對集合成員或集合本身執行基本 CRUD 操作,如下表所述 -

操作 HTTP 方法 狀態程式碼 內容
Retrieve GET 200 表示資源的 Atom 條目
Create POST 201 通過 Location 和 Content-Location 標頭建立的新資源的 URI
Update PUT 200 表示資源的 Atom 條目
Delete DELETE 200 沒有