4

When building an application in Azure Functions you can specify the HTTP Methods that are accepted in the function.json

Given an API that you can do multiple functions on (GET, PUT POST etc) what is the best way to create that function or functions.

There will be shared logic and libraries that need to be available, so I'm looking for a pattern that can enable all the MEthods in a single class, but not sure how you would define that in a function.json such that each HTTP Method could have its own entry point.

The other option is to create a function that basically chooses the method and class that function but this seems like some middleware overhead that I"m sure can be handled in a better way.

i.e. I don't think I should do this for every object that I create a function for and there must be a better pattern.

 async HandleRequest(){
        return validateJwt(function(context,req){
            if(req.method === 'GET'){
            }
            else if(req.method === 'POST'){

            }
            else if(req.method === 'DELETE'){

            }
            else if(req.method === 'PUT'){

            }
            else if(req.method === 'PATCH'){

            }
        });
    }
Cindy Pau
  • 13,085
  • 1
  • 15
  • 27
Bluephlame
  • 3,901
  • 4
  • 35
  • 51

2 Answers2

6

So the best method for this is to use multiple functions.

You can define functions by route and method in the function.json file. see the example.

Notice route:family/{id:int} this is the only route that this function will handle. you also put in the "methods": ["get"] To restrict the function to a GET.

Create a function per METHOD to have more maintainability in your code. I then use some middleware functionality (which does auth and error handling) before I have a common FamilyHandler Class that does the CRUD operations, including managing the connection to the database.

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["get"],
      "route": "family/{id:int}"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

I discovered this in the following documentation https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=javascript

Bluephlame
  • 3,901
  • 4
  • 35
  • 51
  • I think that's just an example ... Function doesn't limit you and you dont have to allow only one method per function. It is completely feasible to process the different request in the code after entering function. – Cindy Pau May 22 '20 at 08:56
  • 3
    Correct, but it is terribly unmaintainable. The intent of the question was to find the best way to do this. I believe that this is currently the best way, not the only way. I had the if statements in my code and it was becoming very long, especially for multiple objects being retrieved and saved. Now I have very concise source files following the single responsibility principle. – Bluephlame May 22 '20 at 09:06
  • Ok...If this question is over, you can mark yourself answer as the answer to this question.:) – Cindy Pau May 22 '20 at 09:09
1

Your function.json should like this:

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

By default, if methods is not specified, then the function accepts all methods.

Cindy Pau
  • 13,085
  • 1
  • 15
  • 27
  • 1
    Correct, but should I create a Function pre Method (And specify it in the binding) or use code like I have listed above to decide what to do per HTTP Method. – Bluephlame May 21 '20 at 03:12
  • @Bluephlame Yes, you are right. If there are multiple types of methods mapped to functions, you must add logic in your code to process. The code you showed in the question is the correct way. – Cindy Pau May 21 '20 at 05:58