{"id":320,"date":"2020-09-08T10:00:10","date_gmt":"2020-09-08T17:00:10","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sql\/?p=320"},"modified":"2020-09-10T10:31:17","modified_gmt":"2020-09-10T17:31:17","slug":"rest-api-with-azure-functions-javascript-and-azuresql","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sql\/rest-api-with-azure-functions-javascript-and-azuresql\/","title":{"rendered":"Serverless REST API with Azure Functions, Node, JSON and Azure SQL"},"content":{"rendered":"<p>Javascript \/ Typescript (and thus Node) are, among Full-Stack and Back-End developers, one of the most common choices to create scalable, elegant, high-performance, REST API to be used by the most diverse clients. Azure Functions are another pretty popular solution that developers use to create scalable solution without having to deal with all the infrastructural woes, as it\u00a0 just allow you to code you own function, deploy it and&#8230;.done! No IIS or Apache to configure and monitor, no headaches to setup, configure and maintain a load-balanced cluster&#8230;.just the sheer joy of coding!<\/p>\n<p>Now, as a developer I&#8217;d love to be able to use Node and Azure Functions with the database of my choice which, as you can already guess, it Azure SQL. I have already explained extensively (<a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/10-reasons-to-use-azure-sql-in-your-next-project\/\">here<\/a> and <a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/architecting-rest-api-with-python-flask-and-azure-sql\/\">here<\/a>, for example) why I think Azure SQL is just the perfect database for the cloud, so I decided to try to create a REST endpoint just using Azure Functions, Azure SQL and Node.<\/p>\n<p>I&#8217;m quite new to Node so I thought it could be helpful for anyone in my situation to share what I have learned. Here we go!<\/p>\n<h2>Recipe for KISS<\/h2>\n<p>I really wanted to follow the KISS principle, so I decided to avoid any additional library and just go with Tedious, the most widely used Node package for SQL Server \/ Azure SQL. I also wanted to everything in the most javascript-friendly way possible, which means manipulating objects and JSON instead of SQL statements or anything that would remind me that behind the scene I have a (post-)relational database. From this point of view, NoSQL databases usually offer a great user experience as everything is already JSON, and so there is basically nothing special to do to manipulate data. <em>You send JSON, you get JSON, as simple as that<\/em>. With Azure SQL is possible too and, on top of that, you&#8217;ll get all the additional goodness that Azure SQL offers.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-large wp-image-380\" src=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2020\/08\/node-sql-json-1024x620.png\" alt=\"Image node sql json\" width=\"640\" height=\"388\" srcset=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2020\/08\/node-sql-json-1024x620.png 1024w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2020\/08\/node-sql-json-300x182.png 300w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2020\/08\/node-sql-json-768x465.png 768w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2020\/08\/node-sql-json-1536x930.png 1536w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2020\/08\/node-sql-json-2048x1240.png 2048w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/p>\n<h2>Azure Function and Tedious<\/h2>\n<p>First of all, you need to create an Azure Function and this can be easily done using the Azure Function CLI. Make sure you have it installed and than simply run<\/p>\n<pre><code class=\"bash\">func init --worker-runtime node --language javascript\r\n<\/code><\/pre>\n<p>in an empty folder that you&#8217;ll use as Azure Function working folder. Then add a new function<\/p>\n<pre><code class=\"bash\">func new --template HttpTrigger --name customer\r\n<\/code><\/pre>\n<p>Everything is now already ready to be used, and you can start Azure Function runtime locally just by running<\/p>\n<pre><code class=\"bash\">func start\r\n<\/code><\/pre>\n<p>Azure Function will start to listen on <em>localhost<\/em>, and you can already start to use the created REST endpoint by issuing a GET request, for example, at<\/p>\n<pre><code>http:\/\/localhost:7071\/api\/customer\r\n<\/code><\/pre>\n<p>using your a REST client like cUrl or <a href=\"https:\/\/insomnia.rest\/\">Insomnia<\/a> (or your favorite one). The REST endpoint doesn&#8217;t do much at the moment, and you still need to connect it to Azure SQL. To do that you have to install the Tedious package (make sure you are\u00a0<em>in<\/em> the created Azure Function folder, where you can see also the file <em>host.json<\/em>)<\/p>\n<pre><code class=\"bash\">npm install tedious    \r\n<\/code><\/pre>\n<p>and you&#8217;re good to go. You can now open your favorite editor (Visual Studio or Visual Studio Code in my case) and start to create a REST endpoint that will handle HTTP request to implement CRUD operation for our sample Customer endpoint. I won&#8217;t enter into detail of how to use Tedious as it is pretty simple, and also it has quite <a href=\"http:\/\/tediousjs.github.io\/tedious\/\">good documentation on its website<\/a>; it will be enough to say that you just have to follow to usual pattern:<\/p>\n<ul>\n<li>Connect to Azure SQL via the <code>Connection<\/code> object<\/li>\n<li>Execute a command, via the <code>Request<\/code> object<\/li>\n<li>Consume the resultset<\/li>\n<\/ul>\n<h2>Ehy, it doesn&#8217;t work!<\/h2>\n<p>Now, there is only one problem here. If you try to use Tedious with the default Azure Function template, which look like this:<\/p>\n<pre><code class=\"javascript\">module.exports = async function (context, req)\r\n{\r\n    \/*\r\n     * Business Logic here\r\n     *\/\r\n    responseMessage = { customerId: 123, name: \"Davide\" }\r\n\r\n    context.res = {       \r\n        body: responseMessage\r\n    };\r\n}\r\n<\/code><\/pre>\n<p>it won&#8217;t work. Even worse, <strong>it will work without any error, but you&#8217;ll never get a result<\/strong>.<\/p>\n<p>The reason, as per my (limited, as I&#8217;m pretty new to this) understanding, is that Tedious doesn&#8217;t support the async\/await pattern which is instead used by default by Azure Functions. The solution is to remove the <code>async<\/code> keyword from the function definition and then make sure the HTTP response is properly sent back by setting it in the <code>context<\/code> object, provided by Azure Function runtime. Once the HTTP response is ready to be sent, a call to <code>context.done()<\/code> is needed to inform Azure Function that work is done. Everything is explained here:<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/azure\/azure-functions\/functions-reference-node#contextdone-method\">Azure Functions JavaScript developer guide: context.done method<\/a><\/p>\n<p>Here&#8217;s the pseudo-code needed to make it work (GitHub repo with fully working code is also available, just keep reading)<\/p>\n<pre><code>define Connection object\r\ndefine Request object\r\n  if Request fails \r\n    set HTTP status to 500\r\n  once Request is done\r\n    put Request result into context.res\r\n  call context.done()\r\nopen Connection\r\n  if Connection fails \r\n    set HTTP status to 500\r\n    call context.done()\r\n  else\r\n    execute Request\r\n<\/code><\/pre>\n<p>Once you know that, is pretty easy.<\/p>\n<h2>Ok, enough with columns and rows<\/h2>\n<p>As written at the beginning, as a developer I feel much more comfortable manipulating a JSON object than tables with columns and rows, so I&#8217;d love to be able to get JSON from Azure SQL and send back JSON to the database. Thanks to Azure SQL native JSON support, I can do that. For example, to return a JSON array of all customers that I should return as result of an HTTP GET request I can just do this:<\/p>\n<pre><code class=\"sql\">SELECT \r\n    [CustomerID] AS 'Id', \r\n    [CustomerName] AS 'Name'\r\nFROM \r\n    [Sales].[Customers] \r\nFOR JSON PATH\r\n<\/code><\/pre>\n<p>and the result would be something like:<\/p>\n<pre><code class=\"json\">[\r\n    {\r\n        \"Id\": 832,\r\n        \"Name\": \"Aakriti Byrraju\"\r\n    },\r\n    {\r\n        \"Id\": 836,\r\n        \"Name\": \"Abel Spirlea\"\r\n    },\r\n    {...}\r\n]\r\n<\/code><\/pre>\n<p>This is great for <strong>receiving<\/strong> JSON data from Azure SQL! But what about <strong>sending<\/strong> a JSON so that it will be then stored into an existing table? Easy as before. Let&#8217;s say this is the JSON you&#8217;ll be sending to Azure SQL:<\/p>\n<pre><code class=\"json\">{\r\n    \"CustomerName\": \"John Doe\",\r\n    \"PhoneNumber\": \"123-234-5678\",\r\n    \"FaxNumber\": \"123-234-5678\",\r\n    \"WebsiteURL\": \"http:\/\/www.something.com\",\r\n    \"Delivery\": {\r\n        \"AddressLine1\": \"One Microsoft Way\",\r\n        \"PostalCode\": 98052\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>then this is the T-SQL code that you can use to turn JSON into a table that it can be easily inserted into existing structures:<\/p>\n<pre><code class=\"sql\">SELECT \r\n    * \r\nFROM\r\n    OPENJSON(@Json) WITH\r\n    (       \r\n        [CustomerName] NVARCHAR(100), \r\n        [PhoneNumber] NVARCHAR(20), \r\n        [FaxNumber] NVARCHAR(20), \r\n        [WebsiteURL] NVARCHAR(256),\r\n        [DeliveryAddressLine1] NVARCHAR(60) '$.Delivery.AddressLine1',\r\n        [DeliveryAddressLine2] NVARCHAR(60) '$.Delivery.AddressLine2',\r\n        [DeliveryPostalCode] NVARCHAR(10) '$.Delivery.PostalCode'   \r\n    )\r\n<\/code><\/pre>\n<p>That&#8217;s it!<\/p>\n<p><em>This way we can use the most convenient or correct structure for each language and tool we are using. JSON for Javascript and Tables for SQL.<\/em><\/p>\n<p>If you want, of course, <strong>you could also store JSON also as-is<\/strong>, without the need to turn it into a table, but that will be less efficient. Depending what you want and need to do, choose what&#8217;s the best for you. In case you decide to store JSON as-is, remember that you can also <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/relational-databases\/json\/index-json-data\">create indexes on JSON documents<\/a>. If you are unsure which strategy would be the most suitable for your scenario &#8211; JSON or proper tables &#8211; this article can surely help you decide: <a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/json-in-your-azure-sql-database-lets-benchmark-some-options\/\">JSON in your Azure SQL Database? Let\u2019s benchmark some options!<\/a><\/p>\n<h2>Conclusion<\/h2>\n<p>Using Node with Azure SQL has never been easier thanks to JSON acting as a <em>trait d&#8217;union<\/em> between the two different worlds. It finally seems that the days of <em>impedance mismatch<\/em> are finally gone. So it&#8217;s now time to fully take advantage of two truly amazing technologies like Node and Azure SQL.<\/p>\n<p>With Azure SQL you can have Row-Level Security, Change Tracking, Encryption, Columnstore, Lock-Free tables, <a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/10-reasons-to-use-azure-sql-in-your-next-project\/\">and much more<\/a>&#8230;.all usable via JSON integration.<\/p>\n<p>Give it a test drive yourself, by deploying on Azure the code available here:<\/p>\n<p><a href=\"https:\/\/github.com\/Azure-Samples\/azure-sql-db-node-rest-api\">Creating a REST API with Azure Functions, Node and Azure SQL GitHub Code Repo<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Javascript \/ Typescript (and thus Node) are, among Full-Stack and Back-End developers, one of the most common choices to create scalable, elegant, high-performance, REST API to be used by the most diverse clients. Azure Functions are another pretty popular solution that developers use to create scalable solution without having to deal with all the infrastructural [&hellip;]<\/p>\n","protected":false},"author":24720,"featured_media":380,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,430,429],"tags":[409,434,435,432,29,431,410,433],"class_list":["post-320","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sql","category-javascript","category-node","tag-api","tag-azure","tag-functions","tag-javascript","tag-json","tag-node","tag-rest","tag-serverless"],"acf":[],"blog_post_summary":"<p>Javascript \/ Typescript (and thus Node) are, among Full-Stack and Back-End developers, one of the most common choices to create scalable, elegant, high-performance, REST API to be used by the most diverse clients. Azure Functions are another pretty popular solution that developers use to create scalable solution without having to deal with all the infrastructural [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/320","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/users\/24720"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/comments?post=320"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/320\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media\/380"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media?parent=320"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/categories?post=320"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/tags?post=320"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}