開發函數計算的正確姿式 —— Fun validate 語法校驗排錯指南

1. 前言

首先介紹下在本文出現的幾個比較重要的概念:node

函數計算(Function Compute): 函數計算是一個事件驅動的服務,經過函數計算,用戶無需管理服務器等運行狀況,只需編寫代碼並上傳。函數計算準備計算資源,並以彈性伸縮的方式運行用戶代碼,而用戶只需根據實際代碼運行所消耗的資源進行付費。git

Fun: Fun 是一個用於支持 Serverless 應用部署的工具,能幫助您便捷地管理函數計算、API 網關、日誌服務等資源。它經過一個資源配置文件(template.yml),協助您進行開發、構建、部署操做。github

template.yml: template.yml 用於定義 serverless 應用的模型。不管是使用 fun local 仍是 fun deploy 等功能,都是經過解析 tempalte.yml 的內容,構建出用戶定義的雲資源模型,進而實現本地雲資源的運行調試以及發佈等功能。json

template.yml 所描述的 Serverless 模型,是 Fun 全部功能的基石。template.yml 的正確性對後續可以順利使用 Fun 的各項功能無疑是很是關鍵的。爲了幫助用戶更快速的修正 template.yml 中錯誤的描述,咱們在 Fun 2.14.0 優化了語法校驗的錯誤信息,能夠達到更精準定位報錯並修復的目的。服務器

下面咱們就經過一個示例,學習如何根據報錯信息糾正 template.yml 中的錯誤語法描述。less

備註:請確保 Fun 工具版本在 2.14.0+函數

2. 錯誤的 template.yml 示例

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  local-http-demo:
    Type: 'Aliyun::Serverless::InvalidService'
    Properties:
      Description: 'local invoke demo'
    nodejs8:
      Type: 'Aliyun::Serverless::InvalidFunction'
      Properties:
        Handler: index.handler
        CodeUri: nodejs8/
        Description: 'http trigger demo with nodejs8!'
      Events:
        http-test:
          Type: HTTP
          Properties:
            AuthType: ANONYMOUS
            Method: ['GET', 'POST', 'PUT']

在上面的示例中,咱們原意是想要描述一個叫作 local-http-demo 的服務,並在服務下定義了一個名爲 nodejs8 的函數,同時爲該函數配置一個匿名的 HTTP 觸發器,支持 GET、POST、PUT 的 HTTP 請求。工具

但遺憾的是,上面的示例描述有幾處比較隱蔽的問題。下面,咱們就動手實踐,看如何發現上面示例中包含的錯誤語法描述並將其修正。學習

3. 語法錯誤發現並修復

3.1 修復第一個錯誤

咱們能夠執行 fun validate 對 tempalte.yml 進行校驗(其餘的命令好比 deploy、local 等也會隱式的執行 fun validate,保證在語法描述正確的狀況下才執行指定的功能)。優化

當執行完 fun validate 後,會看到錯誤信息:

[
  {
    "keyword": "enum",
    "dataPath": "/Resources/local-http-demo/Type",
    "params": {
      "allowedValues": [
        "Aliyun::Serverless::Service",
        "Aliyun::Serverless::TableStore",
        "Aliyun::Serverless::Api",
        "Aliyun::Serverless::Log",
        "Aliyun::Serverless::CustomDomain",
        "Aliyun::Serverless::MNSTopic"
      ]
    },
    "message": "should be equal to one of the allowed values"
  }
]

錯誤信息會以 json 的格式輸出,其中的 message 就是咱們的本次的錯誤緣由,dataPath 是遇到的錯誤在 template.yml 中的具體位置,params 中的內容是對 message 的進一步的補充。

按照咱們剛纔的解釋,大概就能夠明白,/Resources/local-http-demo/Type 這個資源定義出了問題,緣由是這個值應該是 Aliyun::Serverless::ServiceAliyun::Serverless::TableStoreAliyun::Serverless::ApiAliyun::Serverless::LogAliyun::Serverless::CustomDomainAliyun::Serverless::MNSTopic 中的一個。

再看下咱們的描述(限於篇幅只列出了 template.yml 的部份內容):

Resources:
  local-http-demo:
    Type: 'Aliyun::Serverless::InvalidService'

很明顯,咱們描述的 Aliyun::Serverless::InvalidService 並不在上面容許的值中。

咱們將其修改正確,也就是把 Aliyun::Serverless::InvalidService 修改成 Aliyun::Serverless::Service 便可。

Resources:
  local-http-demo:
-    Type: 'Aliyun::Serverless::InvalidService'
+    Type: 'Aliyun::Serverless::Service'

3.2 從新進行語法校驗並修復

一般狀況下,咱們建議的方式是修復完一個問題,就從新使用 fun validate 進行校驗。

咱們將上面問題修復後,從新執行 fun validate 後,能夠發現,依舊有報錯:

[
  {
    "keyword": "const",
    "dataPath": "/Resources/local-http-demo/nodejs8/Type",
    "params": {
      "allowedValue": "Aliyun::Serverless::Function"
    },
    "message": "should be equal to constant"
  },
  {
    "keyword": "required",
    "dataPath": "/Resources/local-http-demo/nodejs8/Properties",
    "params": {
      "missingProperty": "Runtime"
    },
    "message": "should have required property 'Runtime'"
  },
  {
    "keyword": "additionalProperties",
    "dataPath": "/Resources/local-http-demo/nodejs8/Events/http-test/Properties",
    "params": {
      "additionalProperty": "Method"
    },
    "message": "should NOT have additional properties"
  },
  {
    "keyword": "required",
    "dataPath": "/Resources/local-http-demo/nodejs8/Events/http-test/Properties",
    "params": {
      "missingProperty": "Methods"
    },
    "message": "should have required property 'Methods'"
  }
]

這一次與上一次不一樣,同時出現了 4 個報錯。但具體的修復步驟與上一步是一致的,即先找到第一個問題進行修復就能夠了。

第一個報錯以下:

{
  "keyword": "const",
  "dataPath": "/Resources/local-http-demo/nodejs8/Type",
  "params": {
    "allowedValue": "Aliyun::Serverless::Function"
  },
  "message": "should be equal to constant"
}

這個和咱們剛纔修過的問題是同樣的,意思就是 /Resources/local-http-demo/nodejs8/Type 的定義不對,這個值只被容許設定爲 Aliyun::Serverless::Function 。

咱們按照提示的將其修正(限於篇幅只列出了 template.yml 的部份內容):

Resources:
  local-http-demo:
    nodejs8:
-      Type: 'Aliyun::Serverless::InvalidFunction'
+      Type: 'Aliyun::Serverless::Function'

這時候,咱們能夠從新執行下 fun validate,而後再挑選第一個進行修復,咱們這裏限於篇幅,就繼續挑選下一個報錯進行修復了。

{
  "keyword": "required", 
  "dataPath": "/Resources/local-http-demo/nodejs8/Properties",
  "params": {
    "missingProperty": "Runtime"
  },
  "message": "should have required property 'Runtime'"
}

這裏 message 的含義是,缺乏了必要的屬性 Runtime,檢查下咱們的規範文檔對 Function 資源的描述,能夠發現,Runtime 確實是必選的。

咱們按照提示的將其修正(限於篇幅只列出了 template.yml 的部份內容):

Resources:
  local-http-demo:
    Type: 'Aliyun::Serverless::Service'
    nodejs8:
      Type: 'Aliyun::Serverless::Function'
      Properties:
+            Runtime: nodejs8

最後的兩個錯誤,咱們能夠一塊兒看:

{
  "keyword": "additionalProperties",
  "dataPath": "/Resources/local-http-demo/nodejs8/Events/http-test/Properties",
  "params": {
    "additionalProperty": "Method"
  },
  "message": "should NOT have additional properties"
},
{
  "keyword": "required",
  "dataPath": "/Resources/local-http-demo/nodejs8/Events/http-test/Properties",
  "params": {
    "missingProperty": "Methods"
  },
  "message": "should have required property 'Methods'"
}

這兩個的錯誤含義是,咱們在 /Resources/local-http-demo/nodejs8/Events/http-test/Properties這個路徑下,定義了一個不被容許的屬性 Method,而且一樣是在這個路徑下,缺乏了一個必選的屬性 Methods。結合這兩個報錯,咱們就能夠判斷出,咱們將 Methods 錯寫成了 Method。

咱們按照提示的將其修正(限於篇幅只列出了 template.yml 的部份內容):

Resources:
  local-http-demo:
    nodejs8:
      Events:
        http-test:
          Properties:
            AuthType: ANONYMOUS
-           Method: ['GET', 'POST', 'PUT']
+           Methods: ['GET', 'POST', 'PUT']

當將全部的錯誤修復完成後,咱們再從新執行 fun validate,便可發現,咱們的全部錯誤都被修正啦。

接下來,咱們就使用這個 template.yml 完成後續的 fun local、fun deploy 等功能就能夠了。

3.3 修改記錄彙總

咱們將上面全部的改錯記錄記錄以下:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  local-http-demo:
-   Type: 'Aliyun::Serverless::InvalidService'
+   Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: 'local invoke demo'
    nodejs8:
-     Type: 'Aliyun::Serverless::InvalidFunction'
+     Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: index.handler
        CodeUri: nodejs8/
        Description: 'http trigger demo with nodejs8!'
+       Runtime: nodejs8
      Events:
        http-test:
          Type: HTTP
          Properties:
            AuthType: ANONYMOUS
-           Method: ['GET', 'POST', 'PUT']
+           Methods: ['GET', 'POST', 'PUT']

4. 總結

雖然 Fun 的規範文檔描述的比較詳細了,並且在 Fun 的 repo 首頁,咱們給出了很是多的示例文章,但依舊存在很大可能性會遇到各類各樣的相似上面示例的書寫錯誤。

所以,Fun 提供了比較強大的語法校驗功能,並經過精準的報錯信息,讓用戶能夠方便的將其修正。


原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索