<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joe Gatt</title>
    <description>The latest articles on DEV Community by Joe Gatt (@joegatt).</description>
    <link>https://dev.to/joegatt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F283042%2F6066253c-1ab9-4b43-b730-c3a9534d89a8.jpg</url>
      <title>DEV Community: Joe Gatt</title>
      <link>https://dev.to/joegatt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joegatt"/>
    <language>en</language>
    <item>
      <title>Setting up a Debugging Environment for Azure Functions 2.x using VS Code</title>
      <dc:creator>Joe Gatt</dc:creator>
      <pubDate>Sat, 18 Jan 2020 02:52:02 +0000</pubDate>
      <link>https://dev.to/joegatt/setting-up-a-debugging-environment-for-azure-functions-2-x-using-vs-code-4e0m</link>
      <guid>https://dev.to/joegatt/setting-up-a-debugging-environment-for-azure-functions-2-x-using-vs-code-4e0m</guid>
      <description>&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Debugging Azure Functions can be extremely easy if you add the appropriate logging and error handling to your code. However, there are going to be times where debugging with these techniques is simply not enough. As a result, we need a robust debugging environment to trace a transaction end to end. Before I get to the environment setup, I want to first outline the high-level transaction flow (as I understand it) for Azure Functions. Please refer to the diagram below, which was posted in March 2018 in the Azure Function Python Worker wiki &lt;a href="https://github.com/Azure/azure-functions-python-worker/wiki/Worker-Architecture"&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hYvPpyqC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2u91at3fhf98ylkqiqpu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hYvPpyqC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2u91at3fhf98ylkqiqpu.png" alt="Architecture" title="Azure Functions Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overall, the Azure Functions Host is the host/runtime that powers Azure Functions apps. Starting at the top of the diagram, incoming HTTP transactions are first routed to the WebHost, which is a sub-component of Azure Functions Host. The WebHost processes the HTTP request and sends the transactions to the Azure Functions Python Worker aka the Python Worker. The Python Worker then routes the transaction to the appropriate function app. It is apparent from this diagram to appropriately debug an Azure Function; you need to insert yourself into the Azure Functions Host, which is a dotnet core app written in C#. Please note that for the purposes of this tutorial, I am focused on debugging HTTP Trigger function apps. This tutorial assumes that you have a working understanding of Azure Functions and VS Code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Software Pre-Requisites
&lt;/h3&gt;

&lt;p&gt;There are two pre-requisites necessary to build and debug Azure Functions Host: dotnet core and Visual Studio (VS) Code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;dotnet core 2.2.x:

&lt;ul&gt;
&lt;li&gt;Download dotnetcore-sdk 2.x from &lt;a href="https://dotnet.microsoft.com/download/dotnet-core/2.2"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Validate the checksum of the download by running:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;Openssl sha512 dotnet-sdk-2.2.207-osx-x64.pkg&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;VS Code:

&lt;ul&gt;
&lt;li&gt;Download VS Code from &lt;a href="https://code.visualstudio.com/download"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install the C# and Python extensions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Environment Setup
&lt;/h3&gt;

&lt;p&gt;The following steps help create a stand-alone virtual environment where you can independently debug function apps separate from your other function app development environments. To begin, create a virtual environment and supporting folder structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .afhvenv
&lt;span class="nb"&gt;cd&lt;/span&gt; .afhvenv/
&lt;span class="nb"&gt;source &lt;/span&gt;bin/activate
&lt;span class="nb"&gt;mkdir &lt;/span&gt;afdebugenv
&lt;span class="nb"&gt;cd &lt;/span&gt;afdebugenv
&lt;span class="nb"&gt;mkdir &lt;/span&gt;functions
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you will see later in the article, following the above folder structure will allow you to debug multiple versions of the Azure Functions Host at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure Functions Host Source Code
&lt;/h3&gt;

&lt;p&gt;Download source code of Azure Functions Host’s latest production release. Please note: you can, of course, download any branch you want from GitHub; however, I want what’s running in production since non-production branches may not build successfully. From the root of the afdebugenv run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://github.com/Azure/azure-functions-host/archive/2.0.12888.zip
unzip 2.0.12888.zip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When finished, you will build the debug version of the Azure Function Host from source using the dotnet executable from the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;azure-functions-host-2.0.12888
dotnet build &lt;span class="nt"&gt;-c&lt;/span&gt; Debug WebJobs.Script.sln
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This build will take a few minutes to complete and should build with no errors (even on my MacBook Pro).&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure Functions Host Symbol Files
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/symbols-and-symbol-files"&gt;Symbol files&lt;/a&gt; hold a variety of data that are not actually needed when running the binaries, but which could be very useful in the debugging process. Symbol files are specific for each version of the software, so we are going to create a symbol folder in our Azure Functions Host folder. From the root of the version of Azure Functions Host that you are debugging run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;symbols
wget https://github.com/Azure/azure-functions-host/releases/download/2.0.12888/Functions.Symbols.2.0.12888.win-x64.zip
unzip Functions.Symbols.2.0.12888.win-x64.zip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Azure Functions Python Worker
&lt;/h3&gt;

&lt;p&gt;The Azure Functions Host ships with a python worker which we will use for debugging purposes. Please note: the below path is specific to my setup (OS X), the path to your worker.py will be some variation after “../netcoreapp2.2/workers..”. From the worker directory, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /azure-functions-host-2.0.12888/src/WebJobs.Script.WebHost/bin/Debug/netcoreapp2.2/workers/python/3.7/OSX/X64
wget https://gist.githubusercontent.com/gattjoe/2b2e77a14cd461a131eee9ebc1539f0d/raw/a1c52c3bfb5be87b21bcdfd1e09fbea787ae06ed/worker.config.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After you download worker.config.json to the worker directory, you have to configure the python worker to run in debug mode when it is called by VS code. For some background on the proper format of the worker.config.json file, refer to this &lt;a href="https://github.com/Azure/azure-functions-host/wiki/Authoring-&amp;amp;-Testing-Language-Extensions"&gt;document&lt;/a&gt;. To enable debugging on the worker.py process, add the following directive to worker.config.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"Arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-m ptvsd --host 127.0.0.1 --port 9091"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  VS Code Setup
&lt;/h3&gt;

&lt;p&gt;Launch.json and tasks.json need to be customized to properly build and debug the Azure Functions Host. I am providing example files that will allow you to get up and running much quicker, which is why I was so specific as to the naming of directories above. Once you are comfortable, feel free to customize the launch.json file to meet your needs. At the root of the afdebugenv folder, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; .vscode
&lt;span class="nb"&gt;cd&lt;/span&gt; .vscode
wget https://gist.githubusercontent.com/gattjoe/ce03f5d7ea8294246efabaf048eb1c39/raw/820109fcdbd72b407c49b2c6e7aa9d68db03318a/tasks.json
wget https://gist.githubusercontent.com/gattjoe/47b9e54f25d1d21800f02dd518d86bbb/raw/177908cf773e27f2936458200ba14484d6a55d4e/launch.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When finished, open VS Code from the afdebugenv directory. You may get a notice that says, “Required assets to build and debug are missing from ‘afdebugenv’. Add them?”. Say yes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Additional Python Packages
&lt;/h3&gt;

&lt;p&gt;We are effectively running the entire Azure Function stack locally, so we need to install ptvsd and Azure functions. Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;ptvsd azure-functions
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Validating Your Environment
&lt;/h3&gt;

&lt;p&gt;If you made it this far, kudos to you. I thought about automating this entire process, but I figured that given the rapid pace of change in this space, it would be obsolete within a few months. Assuming you have a plain vanilla HTTP Trigger function app in your functions directory, we are going to run a short test below to ensure your environment is ready to start debugging. From the root of your afdebugenv directory, open up VS Code and perform the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the explorer screen, navigate to the following path: “afdebugenv/azure-functions-host-2.0.12888/src/WebJobs.Script.WebHost/Middleware/FunctionInvocationMiddleware.cs”&lt;/li&gt;
&lt;li&gt;In the first third of the code, you will find the following function definition: “public async Task Invoke(HttpContext context)”. Set a breakpoint in the left-hand gutter, which will be marked by a red dot&lt;/li&gt;
&lt;li&gt;To invoke the debugger for Azure Functions Host, in the debug screen, under the “debug and run” heading, select “.NET Core Launch” from the drop-down and press F5&lt;/li&gt;
&lt;li&gt;You will notice that the integrated terminal opened with similar startup messages appearing as when you execute “func host start”. The only main difference is that the Azure Function Host is listening on port 5000. Please refer to the screenshot below:
 &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dGSzw_yg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bdwbtk8wxne15swpy888.png" alt="FunctionHost" title="Azure Function Host Startup"&gt;
&lt;/li&gt;
&lt;li&gt;To invoke the debugger for the python worker, in the debug screen, under the “debug and run” heading, select “Attach to Python Functions” from the drop-down and press F5&lt;/li&gt;
&lt;li&gt;Run a test transaction against your HTTPTrigger&lt;/li&gt;
&lt;li&gt;The debugger should hit the breakpoint that you set in step 2, and you can now inspect the data that was passed to the function. Please refer to the screenshot below:
 &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sFt6XisU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oh133pz8d52as4r4w2s6.png" alt="Breakpoint" title="Breakpoint"&gt;
&lt;/li&gt;
&lt;li&gt;To continue processing the transaction, hit F5. On your terminal where you executed the command, you should see your output. Additionally, the integrated terminal should reflect that you processed the transaction successfully&lt;/li&gt;
&lt;li&gt;To exit the debugging process, press the red square in the debugging control panel&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Please note: Stopping the VS Code debugger will NOT kill the worker.py process spawned by Azure Functions Host. As a result, you have to manually kill the process to free ports TCP 5000/5001 back up.  Please note x2: you have to stop the VS Code debugger FIRST, otherwise, the Azure Functions Host will continually spawn up worker.py processes every time you kill it.&lt;/p&gt;

&lt;p&gt;In future articles, I will be covering advanced debugging topics that rely on this article as a foundation. If you have any feedback, please send me a note at gattjoseph at hotmail.&lt;/p&gt;

</description>
      <category>python</category>
      <category>serverless</category>
      <category>azurefunctions</category>
      <category>azure</category>
    </item>
    <item>
      <title>Configuring HTTP Route Parameters in Azure Functions 2.x using Python</title>
      <dc:creator>Joe Gatt</dc:creator>
      <pubDate>Sat, 04 Jan 2020 14:43:26 +0000</pubDate>
      <link>https://dev.to/joegatt/configuring-http-route-parameters-in-azure-functions-2-x-using-python-3m2o</link>
      <guid>https://dev.to/joegatt/configuring-http-route-parameters-in-azure-functions-2-x-using-python-3m2o</guid>
      <description>&lt;h2&gt;
  
  
  Overview of How HTTP Routing Works in Azure Functions
&lt;/h2&gt;

&lt;p&gt;For a high-level overview of three popular HTTP routing patterns, refer to &lt;a href="https://dzone.com/articles/the-three-http-routing-patterns-you-should-know"&gt;this&lt;/a&gt; blog post by Lori MacVittie from F5 networks. Moving forward, when I refer to HTTP routing in the context of Azure Functions for the balance of this blog post, I am referring to path-based routing.&lt;/p&gt;

&lt;p&gt;HTTP routing in Azure Functions is responsible for mapping request URIs to endpoints and routing HTTP requests to those endpoints. Additionally, Azure Functions can extract values from the URI contained in the request and use those values for request processing. The latter is a useful way to pass multiple parameters to an HTTP trigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route Prefix
&lt;/h2&gt;

&lt;p&gt;As the name implies, you can customize or remove the default “api” route prefix for HTTP triggers in Azure Functions. See this documentation from Microsoft for reference. To change it, you modify the &lt;strong&gt;host.json&lt;/strong&gt; file and &lt;em&gt;add&lt;/em&gt; the following configuration setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"routePrefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the above example, we are setting the route prefix to “foo”. Please note: this setting is “global” in that if you are hosting more than one function in a function app, this setting will apply to all functions. Given the global nature of the setting, I have not found much value in modifying the default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route Parameters
&lt;/h2&gt;

&lt;p&gt;As outlined above, an HTTP route can serve two purposes in Azure Functions: mapping request URIs to endpoints or request processing. Routes are defined in the &lt;strong&gt;function.json&lt;/strong&gt; file and configured when the function app starts. According to the documentation, route parameter names must be non-empty and cannot contain these characters: {, }, /.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mapping request URI’s to endpoints
&lt;/h3&gt;

&lt;p&gt;This pattern is by far the easiest to implement. Let’s walk through an example where you want to host two versions of an HTTP trigger function in the same function app. In this example, we have an HTTP trigger function named “FirstName”. To add a version to the route, simply modify the function.json file and &lt;em&gt;add&lt;/em&gt; the following configuration setting: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;"route": "v1/FirstName",&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now you can create a similar HTTP trigger function named “FirstName2”, modify the function.json file and &lt;em&gt;add&lt;/em&gt; the following configuration setting:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"route": "v2/FirstName",&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can use this feature to ensure that you do not break compatibility with functions that you publish or to route traffic to a given endpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Request Processing with HTTP Route Parameters
&lt;/h3&gt;

&lt;p&gt;Let’s walk through an example of using a route parameter to customize request processing. Consider the default HTTP trigger template, which takes data passed to the “name” parameter as input and outputs the data passed to the function. Imagine that you want to extend this function to take both a first name and last name, you would &lt;em&gt;add&lt;/em&gt; the following to your function.json file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"route": "FirstNameLastName/{firstname}/{lastname}"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And you would modify your function code to reflect the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Python HTTP trigger function processed a request."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;firstname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route_params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"firstname"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;lastname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route_params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"lastname"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;f"Hello &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;firstname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;lastname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that you use the “route_params” property instead of the “params” property. The full documentation for the HTTPRequest class for Python is &lt;a href="https://docs.microsoft.com/en-us/python/api/azure-functions/azure.functions.httprequest?view=azure-python"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When you run your function locally, you will notice that the URL has been modified from the default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;FirstNameLastName: &lt;span class="o"&gt;[&lt;/span&gt;GET] http://localhost:7071/api/FirstNameLastName/&lt;span class="o"&gt;{&lt;/span&gt;firstname&lt;span class="o"&gt;}&lt;/span&gt;/&lt;span class="o"&gt;{&lt;/span&gt;lastname&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Route Constraints
&lt;/h2&gt;

&lt;p&gt;Adding a constraint to your route parameter allows you to restrict how the routes in function.json are matched. The general syntax is “{parameter:constraint}”. For example, if we want to restrict our FirstNameLastName function to only accept alpha characters for the two routes we previously defined, we would configure it in function.json like the below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"route": "FirstNameLastName/{firstname:alpha}/{lastname:alpha}",&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Given the pay per transaction nature of Azure Functions, this is an excellent way to ensure that only valid transactions are processed by your function app. For a full list of route constraints, refer to this article &lt;a href="https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-constraints"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please note: processing of route constraints is not performed by the function app but instead by the Azure Function Host. The &lt;a href="https://github.com/Azure/azure-functions-host"&gt;Azure Function Host&lt;/a&gt; will return a 404 if you supply it a bad URI. I will cover this topic in a future blog post about debugging route parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mandatory vs. Optional Route Parameters
&lt;/h2&gt;

&lt;p&gt;You can mark HTTP route parameters as optional, which gives you some flexibility in your code. The '?' character marks a parameter as optional and can occur only at the end of the parameter. For example, if we want to mark our last name route parameter as optional in our previous example, we would configure it in our function.json like the below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"route": "FirstNameLastName/{firstname:alpha}/{lastname:alpha?}",&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Please note that if you do not pass lastname to the above URI, the value of the lastname variable in your function code would be &lt;em&gt;None&lt;/em&gt;. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:7071/api/FirstNameLastName/foo/bar
  Hello, foo bar!
curl http://localhost:7071/api/FirstNameLastName/foo
  Hello, foo None!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Please ensure to add proper error handling in your function app if you mark your HTTP route parameters as optional.&lt;/p&gt;

&lt;p&gt;That’s it for now, in my next blog post I will cover how to debug HTTP routing parameters in detail. If you have any feedback, please send me a note at gattjoseph at &amp;lt; hotmail &amp;gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>azurefunctions</category>
      <category>serverless</category>
    </item>
  </channel>
</rss>
