4

What types are allowed as parameters for Azure Function apps written in C# that are only callable through the admin endpoint?

I've read lots of documentation and source code and I still don't know the answer. I'm looking for definitive references and clear explanations as to what that means and why, plus examples of how to implement functions with other parameter types.

I'm wondering if the Azure team expect you to accept a string of JSON and parse it yourself into proper types, but the documentation I've found doesn't say.

Additional context

The specific function I am working on is to be called only via the admin interface so does not have any Http etc bindings.

[NoAutomaticTrigger]
[FunctionName(nameof(SomeFunctionName))]
public async Task SomeFunctionName(ParameterTypeHere someParameterName)
{
...

What can I put instead of ParameterTypeHere?

The specific use I have (this time) is that I want to pass something like List<Guid> or Guid[], I don't mind if I have to wrap it in a class or something but nothing I tried worked so I've ended up splitting a string on comma and parsing out the guids which seems like a poor solution.

Currently I've got a string parameter and am calling it with:

$ curl -v http://localhost:7071/admin/functions/SomeFunctionName \
  -d '{"input": "699F3073-9BFD-4DA7-9E61-4E6564D032EC,197DA362-C281-4E0F-BB92-8759F7A5B4B4"}' \
  -H "Content-Type:application/json"

Research so far

Things I've already looked at that leave me still unsure what I can use beyond string for more complex inputs:

The parameter name is ignored, and you have to pass it in with the name "input" regardless of the actual parameter name. Just another thing to trip over.

Even more context

If you're wondering why you'd ever want an admin-only function, this was for a one-off job to be run by someone else who has access to the admin endpoints. It appeared to be the simplest thing that could work. An HttpTrigger would have been fine, it just appeared to violate YAGNI.

Tim Abell
  • 11,186
  • 8
  • 79
  • 110
  • 1
    as far as i remember, any type that is Serializable is Ok. – Misiakw Jan 11 '21 at 15:19
  • It's possible I'm just doing it all wrong and I should be using an HttpTrigger even though it's a throwaway thing and the admin interface would be fine if I could make it work. – Tim Abell Jan 11 '21 at 15:31
  • yeah I'm wondering if you actually need to tell it what kind of trigger it should be - from what you write it sounds like http – silent Jan 11 '21 at 15:32
  • 1
    when you only want to make an http triggered function available via the Admin interface, you can actually just Disable it (I had a thread on github on this a while ago https://github.com/Azure/azure-functions-core-tools/issues/1763) – silent Jan 11 '21 at 15:36

1 Answers1

2

Some weeks ago, I tested how to convert an API using functions with special attention to DI (not shown in below example) and validation. This may not be a direct answer to your question, but it shows that plain model classes may be used.

public class MyRequestModel
{
    [Display(Name = "Message")]
    [Required, MinLength(3)]
    public string Message { get; set; }
}

public static class MyHttpExample
{
    [FunctionName(nameof(MyHttpExample))]
    public static IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = "test/{message}")] MyRequestModel req, ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        var validationResults = new List<ValidationResult>();
        if (!Validator.TryValidateObject(req, new ValidationContext(req, null, null), validationResults, true))
        {
            return new BadRequestObjectResult(validationResults);
        }

        var responseMessage = $"Hello, {req.Message}. This HTTP triggered function executed successfully.";
        return new OkObjectResult(responseMessage);
    }
}

More information on Azure Functions binding expression patterns https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-expressions-patterns

When reading the above doc, keep in mind that function.json is generated from annotations when using C#, but doc shows what's available. Generated function.json for the above example:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-3.0.11",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "httpTrigger",
      "route": "test",
      "methods": [
        "get"
      ],
      "authLevel": "function",
      "name": "req"
    }
  ],
  "disabled": false,
  "scriptFile": "../bin/MyFunctions.dll",
  "entryPoint": "MyFunctions.MyHttpExample.Run"
}

See also https://stackoverflow.com/a/54489040/14072498

Roar S.
  • 8,103
  • 1
  • 15
  • 37
  • 1
    Thanks, that's definitely worth including here as it highlights the difference between the HttpTrigger and the admin only version - in the Http one there's an `HttpTrigger` attribute on the parameter itself which is absent on the one I'd written, which presumably affects binding behaviour. – Tim Abell Jan 12 '21 at 10:05
  • 1
    Being a bit inexperienced with function apps, I hadn't originally noticed that the http ones have this attribute *on a parameter* and that mine was missing it as I iterated towards the smallest thing that could work. I've updated the question to be clearer that I'd tripped over an issue with the admin variant. Your answer helps clarify an important difference between admin and http endpoints. I think I'm doing something the azure devs didn't consider that anyone would do. – Tim Abell Jan 12 '21 at 10:15