{"id":89877,"date":"2021-02-15T17:03:28","date_gmt":"2021-02-15T17:03:28","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=89877"},"modified":"2021-02-14T12:58:33","modified_gmt":"2021-02-14T12:58:33","slug":"custom-binding-azure-functions","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/custom-binding-azure-functions\/","title":{"rendered":"Custom Binding for Azure Functions"},"content":{"rendered":"<p>Azure Functions are a great development tool, allowing us to create serverless software. However, one detail was bothering me when I create a function: The HTTP Trigger receives a\u00a0<strong>HTTPRequest<\/strong> object and we need to extract the parameters from the request. This becomes kind of a low-level code mixed with our business code. It&#8217;s like going back in time some years.<\/p>\n<p>The solution is simple: we can create a custom binding to extract objects from the <strong>HTTPreques<\/strong>t. I&#8217;m surprised I haven&#8217;t found many references to this online. The most complete reference I found was a reply on stackoverflow: <a href=\"https:\/\/stackoverflow.com\/questions\/45183820\/how-to-pass-parameters-by-post-to-an-azure-function\">https:\/\/stackoverflow.com\/questions\/45183820\/how-to-pass-parameters-by-post-to-an-azure-function<\/a>\u00a0. However, we can still improve the code.<\/p>\n<p>Let&#8217;s see how we can implement this custom binding and how it can improve the development of Azure Functions. We will analyze the classes needed to build the custom binding.<\/p>\n<h3><strong>BindingExtensionProvider<\/strong><\/h3>\n<p>This class is responsible for adding a binding rule to the azure function configuration. While adding the binding rule, a link is stablished between a custom attribute for the binding rule (<strong>FromBodyAttribute<\/strong> in our example) and the binding rule factory (<strong>FromBodyBindingProvider<\/strong>). This is the only purpose of the attribute, stablish this link.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\">    <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">class<\/span> <span style=\"color: #bb0066;font-weight: bold\">BindingExtensionProvider<\/span> : IExtensionConfigProvider\r\n    {\r\n        <span style=\"color: #008800;font-weight: bold\">private<\/span> <span style=\"color: #008800;font-weight: bold\">readonly<\/span> ILogger logger;\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #0066bb;font-weight: bold\">BindingExtensionProvider<\/span>(ILogger&lt;Startup&gt; logger)\r\n        {\r\n            <span style=\"color: #008800;font-weight: bold\">this<\/span>.logger = logger;\r\n        }\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">void<\/span> <span style=\"color: #0066bb;font-weight: bold\">Initialize<\/span>(ExtensionConfigContext context)\r\n        {\r\n            <span style=\"color: #888888\">\/\/ Creates a rule that links the attribute to the binding<\/span>\r\n            context.AddBindingRule&lt;FromBodyAttribute&gt;().Bind(<span style=\"color: #008800;font-weight: bold\">new<\/span> FromBodyBindingProvider(<span style=\"color: #008800;font-weight: bold\">this<\/span>.logger));\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<h3><strong><br \/>\nFromBodyAttribute<\/strong><\/h3>\n<p>It&#8217;s a simple attribute with no special code, but it&#8217;s used by <strong>BindingExtensionProvider<\/strong> to link a parameter in the Azure Function with this binding provider. We can apply the attribute to a parameter and the link will be stablished.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\"><span style=\"color: #0000cc\">    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue)]<\/span>\r\n<span style=\"color: #0000cc\">    [Binding]<\/span>\r\n    <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">sealed<\/span> <span style=\"color: #008800;font-weight: bold\">class<\/span> <span style=\"color: #bb0066;font-weight: bold\">FromBodyAttribute<\/span> : Attribute\r\n    {\r\n    }\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><strong>FromBodyBindingProvider<\/strong><\/h3>\n<p>This class implements the interface <strong>IBindingProvider<\/strong> and works like a factory for our custom binding rule. The <strong>BindingExtensionProvider<\/strong> inserts an instance of this class in the Azure Function configuration.<\/p>\n<p>This class creates the next one, the binding rule. and here I included one small touch of wisdom: The binding rule is generic, the code captures the data type of the parameter in the context and dynamically creates the binding rule using this data type. By doing so, the data type will be identified from the parameter declaration, no additional clutter in the middle.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\">    <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">class<\/span> <span style=\"color: #bb0066;font-weight: bold\">FromBodyBindingProvider<\/span> : IBindingProvider\r\n    {\r\n        <span style=\"color: #008800;font-weight: bold\">private<\/span> <span style=\"color: #008800;font-weight: bold\">readonly<\/span> ILogger logger;\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #0066bb;font-weight: bold\">FromBodyBindingProvider<\/span>(ILogger logger)\r\n        {\r\n            <span style=\"color: #008800;font-weight: bold\">this<\/span>.logger = logger;\r\n        }\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> Task&lt;IBinding&gt; TryCreateAsync(BindingProviderContext context)\r\n        {\r\n            IBinding binding = CreateBodyBinding(logger, context.Parameter.ParameterType);\r\n            <span style=\"color: #008800;font-weight: bold\">return<\/span> Task.FromResult(binding);\r\n        }\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">private<\/span> IBinding <span style=\"color: #0066bb;font-weight: bold\">CreateBodyBinding<\/span>(ILogger log,Type T)\r\n        {\r\n            <span style=\"color: #333399;font-weight: bold\">var<\/span> type = <span style=\"color: #008800;font-weight: bold\">typeof<\/span>(FromBodyBinding&lt;&gt;).MakeGenericType(T);\r\n            <span style=\"color: #333399;font-weight: bold\">var<\/span> a_Context = Activator.CreateInstance(type, <span style=\"color: #008800;font-weight: bold\">new<\/span> <span style=\"color: #333399;font-weight: bold\">object<\/span>[] { log });\r\n            <span style=\"color: #008800;font-weight: bold\">return<\/span> (IBinding)a_Context;\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><strong>FromBodyBinding<\/strong><\/h3>\n<p>This class implements the <strong>IBinding<\/strong> interface. This is the class injected inside Azure Function configuration. It provides an instance of <strong>IValueProvider<\/strong>, responsible to extract the value from the <strong>HTTPRequest<\/strong>.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\">    <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">class<\/span> <span style=\"color: #bb0066;font-weight: bold\">FromBodyBinding<\/span>&lt;T&gt; : IBinding\r\n    {\r\n        <span style=\"color: #008800;font-weight: bold\">private<\/span> <span style=\"color: #008800;font-weight: bold\">readonly<\/span> ILogger logger;\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #0066bb;font-weight: bold\">FromBodyBinding<\/span>(ILogger logger)\r\n        {\r\n            <span style=\"color: #008800;font-weight: bold\">this<\/span>.logger = logger;\r\n        }\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> Task&lt;IValueProvider&gt; BindAsync(BindingContext context)\r\n        {\r\n            <span style=\"color: #888888\">\/\/ Get the HTTP request<\/span>\r\n            <span style=\"color: #333399;font-weight: bold\">var<\/span> request = context.BindingData[<span style=\"background-color: #fff0f0\">\"req\"<\/span>] <span style=\"color: #008800;font-weight: bold\">as<\/span> HttpRequest;\r\n            <span style=\"color: #008800;font-weight: bold\">return<\/span> Task.FromResult&lt;IValueProvider&gt;(<span style=\"color: #008800;font-weight: bold\">new<\/span> FromBodyValueProvider&lt;T&gt;(request, logger));\r\n        }\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #333399;font-weight: bold\">bool<\/span> FromAttribute =&gt; <span style=\"color: #008800;font-weight: bold\">true<\/span>;\r\n\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> Task&lt;IValueProvider&gt; BindAsync(<span style=\"color: #333399;font-weight: bold\">object<\/span> <span style=\"color: #008800;font-weight: bold\">value<\/span>, ValueBindingContext context)\r\n        {\r\n            <span style=\"color: #008800;font-weight: bold\">return<\/span> <span style=\"color: #008800;font-weight: bold\">null<\/span>;\r\n        }\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> ParameterDescriptor <span style=\"color: #0066bb;font-weight: bold\">ToParameterDescriptor<\/span>() =&gt; <span style=\"color: #008800;font-weight: bold\">new<\/span> ParameterDescriptor();\r\n    }\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><strong>FromBodyValueProvider<\/strong><\/h3>\n<p>This class implements the <strong>IValueProvider<\/strong> interface and is the responsible for extracting the object from the <strong>HTTPRequest<\/strong>. This is where we will use the type we got from the original parameter and used as a generic type for the <strong>FromBodyBinding<\/strong> class.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\">    <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">class<\/span> <span style=\"color: #bb0066;font-weight: bold\">FromBodyValueProvider<\/span>&lt;T&gt; : IValueProvider\r\n    {\r\n        <span style=\"color: #008800;font-weight: bold\">private<\/span> HttpRequest request;\r\n        <span style=\"color: #008800;font-weight: bold\">private<\/span> ILogger logger;\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #0066bb;font-weight: bold\">FromBodyValueProvider<\/span>(HttpRequest request, ILogger logger)\r\n        {\r\n            <span style=\"color: #008800;font-weight: bold\">this<\/span>.request = request;\r\n            <span style=\"color: #008800;font-weight: bold\">this<\/span>.logger = logger;\r\n        }\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">async<\/span> Task&lt;<span style=\"color: #333399;font-weight: bold\">object<\/span>&gt; GetValueAsync()\r\n        {\r\n            <span style=\"color: #008800;font-weight: bold\">try<\/span>\r\n            {\r\n                <span style=\"color: #333399;font-weight: bold\">string<\/span> requestBody = <span style=\"color: #008800;font-weight: bold\">await<\/span> <span style=\"color: #008800;font-weight: bold\">new<\/span> StreamReader(<span style=\"color: #008800;font-weight: bold\">this<\/span>.request.Body).ReadToEndAsync();\r\n                T result = JsonConvert.DeserializeObject&lt;T&gt;(requestBody);\r\n                <span style=\"color: #008800;font-weight: bold\">return<\/span> result;\r\n            }\r\n            <span style=\"color: #008800;font-weight: bold\">catch<\/span> (System.Exception ex)\r\n            {\r\n                <span style=\"color: #008800;font-weight: bold\">this<\/span>.logger.LogCritical(ex, <span style=\"background-color: #fff0f0\">\"Error deserializing object from body\"<\/span>);\r\n\r\n                <span style=\"color: #008800;font-weight: bold\">throw<\/span> ex;\r\n            }\r\n        }\r\n\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> Type Type =&gt; <span style=\"color: #008800;font-weight: bold\">typeof<\/span>(<span style=\"color: #333399;font-weight: bold\">object<\/span>);\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #333399;font-weight: bold\">string<\/span> <span style=\"color: #0066bb;font-weight: bold\">ToInvokeString<\/span>() =&gt; <span style=\"color: #333399;font-weight: bold\">string<\/span>.Empty;\r\n    }\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><strong>Linking Everything<\/strong><\/h3>\n<p>The Azure Functions have evolved along the time. Some time ago, Azure functions used the interface <strong>IWebJobsHostBuilder<\/strong> on their startup function. Nowadays this interface was replaced by <strong>IFunctionsHostBuilder<\/strong>.<\/p>\n<p>The old <strong>IWebJobsHostBuilder<\/strong> interface had a direct method to add the binding extension. On the other hand, the <strong>IFunctionsHostBuilder<\/strong> doesn&#8217;t. In order to solve this problem we need to use a strange workaround.<\/p>\n<p>Once again, stackoverflow comes to the rescue. This link explains the workaround: <a href=\"https:\/\/stackoverflow.com\/questions\/57564396\/how-do-i-mix-custom-parameter-binding-with-dependency-injection-in-azure-functio\">https:\/\/stackoverflow.com\/questions\/57564396\/how-do-i-mix-custom-parameter-binding-with-dependency-injection-in-azure-functio<\/a><\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\">        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">override<\/span> <span style=\"color: #008800;font-weight: bold\">void<\/span> <span style=\"color: #0066bb;font-weight: bold\">Configure<\/span>(IFunctionsHostBuilder builder)\r\n        {\r\n            <span style=\"color: #333399;font-weight: bold\">string<\/span> SqlConnection = Environment.GetEnvironmentVariable(<span style=\"background-color: #fff0f0\">\"SqlConnectionString\"<\/span>);\r\n            builder.Services.AddDbContext&lt;VotingContext&gt;(x =&gt; x.UseSqlServer(SqlConnection));\r\n\r\n\r\n            <span style=\"color: #888888\">\/\/ IWebJobsBuilders instance<\/span>\r\n            <span style=\"color: #333399;font-weight: bold\">var<\/span> wbBuilder = builder.Services.AddWebJobs(x =&gt; { <span style=\"color: #008800;font-weight: bold\">return<\/span>; });\r\n\r\n            <span style=\"color: #888888\">\/\/ And now you can use AddExtension<\/span>\r\n            wbBuilder.AddExtension&lt;BindingExtensionProvider&gt;();\r\n        }\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><strong>Using the Binding in a Function<\/strong><\/h3>\n<p>The code below is an example of how to use the binding we created in a function.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\"><span style=\"color: #0000cc\">        [FunctionName(\"Voting\")]<\/span>\r\n        <span style=\"color: #008800;font-weight: bold\">public<\/span> <span style=\"color: #008800;font-weight: bold\">async<\/span> Task&lt;IActionResult&gt; RegisterVote(\r\n<span style=\"color: #0000cc\">            [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = \"Sessions\/Vote\")]<\/span>\r\n            HttpRequest req,\r\n            ILogger log, [libTools.Bindings.FromBody] VotesRecord votes)\r\n        {\r\n\r\n        }\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><strong>Conclusion<\/strong><\/h3>\n<p>It&#8217;s always a good practice to create and re-use tools to make our code more high-level, I hope this will help to improve your code.\u00a0I published this custom binding on GitHub, feel free to improve it: <a href=\"https:\/\/github.com\/DennesTorres\/HttpBinding\">https:\/\/github.com\/DennesTorres\/HttpBinding<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Azure Functions are a great development tool, allowing us to create serverless software. However, one detail was bothering me when I create a function: The HTTP Trigger receives a\u00a0HTTPRequest object and we need to extract the parameters from the request. This becomes kind of a low-level code mixed with our business code. It&#8217;s like going&#8230;&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[5364,4658,136367,4162,136298],"coauthors":[6810],"class_list":["post-89877","post","type-post","status-publish","format-standard","hentry","category-blogs","tag-azure","tag-functions","tag-httptrigger","tag-microsoft","tag-serverless"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/89877","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=89877"}],"version-history":[{"count":30,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/89877\/revisions"}],"predecessor-version":[{"id":89924,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/89877\/revisions\/89924"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=89877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=89877"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=89877"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=89877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}