首先介紹下在本文出現的幾個比較重要的概念: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+函數
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 請求。工具
但遺憾的是,上面的示例描述有幾處比較隱蔽的問題。下面,咱們就動手實踐,看如何發現上面示例中包含的錯誤語法描述並將其修正。學習
咱們能夠執行 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::Service
、Aliyun::Serverless::TableStore
、Aliyun::Serverless::Api
、Aliyun::Serverless::Log
、Aliyun::Serverless::CustomDomain
、Aliyun::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 等功能就能夠了。
咱們將上面全部的改錯記錄記錄以下:
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 提供了比較強大的語法校驗功能,並經過精準的報錯信息,讓用戶能夠方便的將其修正。
原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。