[Azure] Azure Logic App - 製作簡單的 API +取得 Azure Storage Table 資料,並且判斷邏輯輸出

2021-01-19

今天要搞點事情,這篇文章我真的寫了一段時間了,應該是說這範例花了我很多時間測試,因為跨越到很多東西,這次我們加玩了 Condition , Inline Code ( javascript) ,所以花了一段時間測試,今天就分享一下測試心得吧..

前置作業,在開始之前,因為撰寫 Inline Code 必須要開啟整合帳號 詳細請參考 https://docs.microsoft.com/zh-tw/azure/logic-apps/logic-apps-enterprise-integration-partners

之後在 Logic App 設定中在 Workflow 有一個地方必須要指定你開啟的 Integration accounts 這樣 Inline code 才能用

現在解釋案例,我寫程式 POST 到 Azure Logic App  的一個 work flow  ,我會去 Azure Storage Table 查詢 Partition Key and RowKey 一致的資料,然後我會寫邏輯,如果失敗 或是 成功回應不同訊息

1. 建立第一個 trigger , When A HTTP Request is Received ,因為要制定傳入的資料,所以 JSON Schema ,相關的觀念可以參考 [C#] 使用 NJsonSchema.CodeGeneration.CSharp 製作 JSON Schema + 驗證 JSON

{ "$id": "http://example.com/example.json", "$schema": "http://json-schema.org/draft-07/schema", "additionalProperties": true, "default": {}, "description": "The root schema comprises the entire JSON document.", "examples": [ { "PK": "dsadsa", "RK": "test" } ], "properties": { "PK": { "$id": "#/properties/PK", "default": "", "description": "An explanation about the purpose of this instance.", "examples": [ "dsadsa" ], "title": "The PK schema", "type": "string" }, "RK": { "$id": "#/properties/RK", "default": "", "description": "An explanation about the purpose of this instance.", "examples": [ "test" ], "title": "The RK schema", "type": "string" } }, "required": [ "PK", "RK" ], "title": "The root schema", "type": "object" }

2. 加入一個 Action 去撈資料,並且設定為 Step1  的傳入的 PK , RK 進行查詢。

3. Step2 有兩種狀況 一個是錯誤 (因為沒拉到資料) ,另一種狀況是成功的 然後我們分別在下面,所以我們加入一個 Condition 去判斷 Partition Key + RowKey 查詢查回來 Partition Key  不等於 null   加入 兩種 inline code 進行判斷並且 輸出. 

True Condition Inline Code ( 也就是成功,不等於null) :

var text = "success"; var body=workflowContext.actions.QUERYUSERDATA.outputs.body; var res={ Status : 'success', PK:body.PartitionKey, RK:body.RowKey, Meta:body.Meta }; return JSON.stringify(res);

False Condition Inline Code (失敗,等於 null ):

var text = "error"; var obj = { Status : 'error', Message : 'Data is not Existed.' }; return JSON.stringify(obj);


這樣透過 C# 程式端這邊 post 到步驟1 的網址就可以拿到各自的 json 答案。

var url = "https://prod-28.southeastasia.logic.azure.com:443/workflows/ed700fc0f27b48cc9f5abaee54c00fea/triggers/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=6u9Y6ZjyNqhWHGcIDJIblT6OZkIX7-xzmHVNc4qrMcQ"; var client = new RestClient(); var request = new RestRequest(url, Method.POST); string jsonToSend = "{\"PK\":\"CLASSA\" , \"RK\":\"LOGICAPPKEY1\"}"; //string jsonToSend = "{\"PK\":\"CLASSA\" , \"RK\":\"ERROR\"}"; request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody); request.RequestFormat = DataFormat.Json; try { var c = client.ExecuteAsPost(request, "POST"); Response.Write(c.Content); } catch (Exception error) { // Log }


附上完整的 Azure Logic App Code :

{ "definition": { "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", "actions": { "Condition": { "actions": { "RES_SUCCESS": { "inputs": { "body": "@outputs('SUCCESS_RESPONSE_JS')?['body']", "statusCode": 200 }, "kind": "Http", "runAfter": { "SUCCESS_RESPONSE_JS": [ "Succeeded" ] }, "type": "Response" }, "SUCCESS_RESPONSE_JS": { "inputs": { "code": "var text = \"success\";\r\n\r\nvar body=workflowContext.actions.QUERYUSERDATA.outputs.body;\r\n\r\nvar res={\r\nStatus : 'success',\r\nPK:body.PartitionKey,\r\nRK:body.RowKey,\r\nMeta:body.Meta\r\n};\r\n\r\nreturn JSON.stringify(res);\r\n" }, "runAfter": {}, "type": "JavaScriptCode" } }, "else": { "actions": { "ERROR_RESPONSE_JS": { "inputs": { "code": "var text = \"error\";\r\n\r\nvar obj = {\r\n Status : 'error',\r\n Message : 'Data is not Existed.'\r\n};\r\n\r\nreturn JSON.stringify(obj);\r\n" }, "runAfter": {}, "type": "JavaScriptCode" }, "RES_FAIL": { "inputs": { "body": "@string(outputs('ERROR_RESPONSE_JS')['body'])", "statusCode": 200 }, "kind": "Http", "runAfter": { "ERROR_RESPONSE_JS": [ "Succeeded" ] }, "type": "Response" } } }, "expression": { "and": [ { "not": { "equals": [ "@body('QUERYUSERDATA')?['PartitionKey']", "@null" ] } } ] }, "runAfter": { "QUERYUSERDATA": [ "Succeeded" ] }, "type": "If" }, "QUERYUSERDATA": { "inputs": { "host": { "connection": { "name": "@parameters('$connections')['azuretables']['connectionId']" } }, "method": "get", "path": "/Tables/@{encodeURIComponent('table1')}/entities(PartitionKey='@{encodeURIComponent(triggerBody()['PK'])}',RowKey='@{encodeURIComponent(triggerBody()['RK'])}')", "queries": { "$select": "Meta,PartitionKey,RowKey" } }, "runAfter": {}, "type": "ApiConnection" } }, "contentVersion": "1.0.0.0", "outputs": {}, "parameters": { "$connections": { "defaultValue": {}, "type": "Object" } }, "triggers": { "manual": { "inputs": { "schema": { "$id": "http://example.com/example.json", "$schema": "http://json-schema.org/draft-07/schema", "additionalProperties": true, "default": {}, "description": "The root schema comprises the entire JSON document.", "examples": [ { "PK": "dsadsa", "RK": "test" } ], "properties": { "PK": { "$id": "#/properties/PK", "default": "", "description": "An explanation about the purpose of this instance.", "examples": [ "dsadsa" ], "title": "The PK schema", "type": "string" }, "RK": { "$id": "#/properties/RK", "default": "", "description": "An explanation about the purpose of this instance.", "examples": [ "test" ], "title": "The RK schema", "type": "string" } }, "required": [ "PK", "RK" ], "title": "The root schema", "type": "object" } }, "kind": "Http", "type": "Request" } } }, "parameters": { "$connections": { "value": { "azuretables": { "connectionId": "/subscriptions/11111111-2222-3333-4444-66666666666/resourceGroups/SPINUS/providers/Microsoft.Web/connections/azuretables", "connectionName": "azuretables", "id": "/subscriptions/11111111-2222-3333-4444-66666666666/providers/Microsoft.Web/locations/southeastasia/managedApis/azuretables" } } } } }


這花了一點時間盡量紀錄完整希望幫助到有碰到的人,看起來很複雜,其實自己做完之後是到還好,只是有些地方沒這麼熟悉,不過為了達到無 server 化的目標跟成本考量,這點研究我覺得蠻值得的..

reference:

https://docs.microsoft.com/zh-tw/azure/logic-apps/logic-apps-add-run-inline-code


當麻許的碎念筆記 2014 | Donma Hsu Design.