Skip to content

How should the PowerShell worker implement $returns (if at all)? #82

Open
@TylerLeonhardt

Description

@TylerLeonhardt

Background

In Azure Functions, there is a concept of "output bindings" which are essentially the output of your function. You define these outputs in the bindings section of the function.json. Here's an example function.json for an HttpTrigger and response:

{
  "disabled": false,
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}

notice the binding Response has a direction of out.

There exists a "special" output binding called $returns which would look like this:

    {
      "type": "http",
      "direction": "out",
      "name": "$returns"
    }

This, in every language that Azure Functions supports in V2, gives the user the ability to "return" the result. Rather than explicitly specifying that value X goes to the output binding of "Foo".

For example, in C# you would normally declare outputs using the out keyword in the function definition:

function.json

    {
      "type": "http",
      "direction": "out",
      "name": "output"
    }

run.cs

public static Run(string input, out string output)
{
    output = "Hello World";
}

But if you want to leverage $returns you would do:

function.json

    {
      "type": "http",
      "direction": "out",
      "name": "$returns"
    }

run.cs

public static Run(string input)
{
    return "Hello World";
}

Note the use of the return keyword.

The problem

PowerShell is different than most languages because it can return multiple things by leveraging the Pipeline.

In addition to that, a lot of folks write to the pipeline as a way to log something.

So implementing $returns for PowerShell is strange because it's not clear what the intended behavior should be.

The possible solutions

Solution 1: Take everything

Everything that gets thrown onto the pipeline, will be added to a list. That list will be set as the output for the output binding $returns. In addition to that, everything added to the pipeline can be logged to the host.

This idea comes from the fact that since PowerShell can "return" multiple things, a list of the things written to the pipeline would be the most "PowerShell-y" experience for $returns.

This does mean that the user would need to log using Write-Host or others instead of simply writing to the pipeline otherwise their log statements will be included in the $returns output.

Solution 2: Take one thing

Everything that gets thrown onto the pipeline will be logged, but the LAST item added to the pipeline will be the output for the output binding $returns.

This idea comes from wanting to align with other languages. It also gives the user the ability to use the pipeline for logging and "returning".

FWIW, AWS Lambda went with this approach - so I've heard.

Solution 3: Take nothing

This would mean that $returns doesn't make sense for PowerShell and the only way to specify output is by using the Push-OutputBinding command.

That said, everything added to the pipeline can be logged to the host.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions