Create an OpenAPI definition for a function

REST APIs are often described using an OpenAPI definition (formerly known as a Swagger file). This definition contains information about what operations are available in an API and how the request and response data for the API should be structured.

In this tutorial, you create a function that determines whether an emergency repair on a wind turbine is cost-effective. You then create an OpenAPI definition for the function app so that the function can be called from other apps and services.

In this tutorial, you learn how to:

  • Create a function in Azure
  • Generate an OpenAPI definition using OpenAPI tools
  • Modify the definition to provide additional metadata
  • Test the definition by calling the function

Create a function app

You must have a function app to host the execution of your functions. A function app lets you group functions as a logic unit for easier management, deployment, scaling, and sharing of resources.

  1. Click the New button found on the upper left-hand corner of the Azure portal.

  2. Click Compute > Function App. Then, use the function app settings as specified in the table.

    Create function app in the Azure portal

    Setting Suggested value Description
    App name Globally unique name Name that identifies your new function app. Valid characters are a-z, 0-9, and -.
    Subscription Your subscription The subscription under which this new function app will be created.
    Resource Group myResourceGroup Name for the new resource group in which to create your function app.
    Hosting plan Consumption plan Hosting plan that defines how resources are allocated to your function app. In the default Consumption Plan, resources are added dynamically as required by your functions. You only pay for the time your functions run.
    Location West Europe Choose a location near you or near other services your functions will access.
    Storage account Globally unique name Name of the new storage account used by your function app. Storage account names must be between 3 and 24 characters in length and may contain numbers and lowercase letters only. You can also use an existing account.
  3. Click Create to provision and deploy the new function app.

Favorite Functions in the portal

If you haven't already done so, add Function Apps to your favorites in the Azure portal. This makes it easier to find your function apps. If you have already done this, skip to the next section.

  1. Log in to the Azure portal.

  2. Click the arrow at the bottom left to expand all services, type Functions in the Filter field, and then click the star next to Function Apps.

    Create function app in the Azure portal

    This adds the Functions icon to the menu on the left of the portal.

  3. Close the menu, then scroll down to the bottom to see the Functions icon. Click this icon to see a list of all your function apps. Click your function app to work with functions in this app.

Create the function

This tutorial uses an HTTP triggered function that takes two parameters: the estimated time to make a turbine repair (in hours); and the capacity of the turbine (in kilowatts). The function then calculates how much a repair will cost, and how much revenue the turbine could make in a 24 hour period.

  1. Expand your function app, click the + button next to Functions, click the HTTPTrigger template. Enter TurbineRepair for the function Name and click Create.

    Function Apps blade, Functions +

  2. Replace the contents of the run.csx file with the following code, then click Save:

    using System.Net;
    
    const double revenuePerkW = 0.12; 
    const double technicianCost = 250; 
    const double turbineCost = 100;
    
    public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
    {   
    
        //Get request body
        dynamic data = await req.Content.ReadAsAsync<object>();
        int hours = data.hours;
        int capacity = data.capacity;
    
        //Formulas to calculate revenue and cost
        double revenueOpportunity = capacity * revenuePerkW * 24;  
        double costToFix = (hours * technicianCost) +  turbineCost;
        string repairTurbine;
    
        if (revenueOpportunity > costToFix){
            repairTurbine = "Yes";
        }
        else {
            repairTurbine = "No";
        }
    
        return req.CreateResponse(HttpStatusCode.OK, new{
            message = repairTurbine,
            revenueOpportunity = "$"+ revenueOpportunity,
            costToFix = "$"+ costToFix         
        }); 
    }
    

    This function code returns a message of Yes or No to indicate whether an emergency repair is cost-effective, as well as the revenue opportunity that the turbine represents, and the cost to fix the turbine.

  3. To test the function, click Test at the far right to expand the test tab. Enter the following value for the Request body, and then click Run.

    {
    "hours": "6",
    "capacity": "2500"
    }
    

    Test the function in the Azure portal

    The following value is returned in the body of the response.

    {"message":"Yes","revenueOpportunity":"$7200","costToFix":"$1600"}
    

Now you have a function that determines the cost-effectiveness of emergency repairs. Next, you generate and modify an OpenAPI definition for the function app.

Generate the OpenAPI definition

Now you're ready to generate the OpenAPI definition. This definition can be used by other Microsoft technologies, like API Apps, PowerApps and Microsoft Flow, as well as third party developer tools like Postman and many more packages.

  1. Select only the verbs that your API supports (in this case POST). This makes the generated API definition cleaner.

    1. On the Integrate tab of your new HTTP Trigger function, change Allowed HTTP methods to Selected methods

    2. In Selected HTTP methods, clear every option except POST.

      Selected HTTP methods

  2. Click your function app name (like function-demo-energy) > Platform features > API definition.

    API definition

  3. On the API definition tab, click Function.

    API definition source

    This step enables a suite of OpenAPI options for your function app, including an endpoint to host an OpenAPI file from your function app's domain, an inline copy of the OpenAPI Editor, and an API definition template generator.

  4. Click Generate API definition template > Save.

    Generate API definition template

    Azure scans your function app for HTTP Trigger functions and uses the info in functions.json to generate an OpenAPI definition. Here's the definition that is generated:

    swagger: '2.0'
    info:
    title: function-demo-energy.azurewebsites.net
    version: 1.0.0
    host: function-demo-energy.azurewebsites.net
    basePath: /
    schemes:
    - https
    - http
    paths:
    /api/TurbineRepair:
        post:
        operationId: /api/TurbineRepair/post
        produces: []
        consumes: []
        parameters: []
        description: >-
            Replace with Operation Object
            #http://swagger.io/specification/#operationObject
        responses:
            '200':
            description: Success operation
        security:
            - apikeyQuery: []
    definitions: {}
    securityDefinitions:
    apikeyQuery:
        type: apiKey
        name: code
        in: query
    

    This definition is described as a template because it requires more metadata to be a full OpenAPI definition. You'll modify the definition in the next step.

Modify the OpenAPI definition

Now that you have a template definition, you modify it to provide additional metadata about the API's operations and data structures. In API definition, delete the generated definition from post to the bottom of the definition, paste in the content below, and click Save.

    post:
      operationId: CalculateCosts
      description: Determines if a technician should be sent for repair
      summary: Calculates costs
      x-ms-summary: Calculates costs
      x-ms-visibility: important
      produces:
        - application/json
      consumes:
        - application/json
      parameters:
        - name: body
          in: body
          description: Hours and capacity used to calculate costs
          x-ms-summary: Hours and capacity
          x-ms-visibility: important
          required: true
          schema:
            type: object
            properties:
              hours:
                description: The amount of effort in hours required to conduct repair
                type: number
                x-ms-summary: Hours
                x-ms-visibility: important
              capacity:
                description: The max output of a turbine in kilowatts
                type: number
                x-ms-summary: Capacity
                x-ms-visibility: important
      responses:
        200:
          description: Message with cost and revenue numbers
          x-ms-summary: Message
          schema:
           type: object
           properties:
            message:
              type: string
              description: Returns Yes or No depending on calculations
              x-ms-summary: Message 
            revenueOpportunity:
              type: string
              description: The revenue opportunity cost
              x-ms-summary: RevenueOpportunity 
            costToFix:
              type: string
              description: The cost in $ to fix the turbine
              x-ms-summary: CostToFix
      security:
        - apikeyQuery: []
definitions: {}
securityDefinitions:
  apikeyQuery:
    type: apiKey
    name: code
    in: query

In this case you could just paste in updated metadata, but it's important to understand the types of modifications we made to the default template:

  • Specified that the API produces and consumes data in a JSON format.

  • Specified the required parameters, with their names and data types.

  • Specified the return values for a successful response, with their names and data types.

  • Provided friendly summaries and descriptions for the API, and its operations and parameters. This is important for people who will use this function.

  • Added x-ms-summary and x-ms-visibility, which are used in the UI for Microsoft Flow and Logic Apps. For more information, see OpenAPI extensions for custom APIs in Microsoft Flow.

Note

We left the security definition with the default authentication method of API key. You would change this section of the definition if you used a different type of authentication.

For more information about defining API operations, see the Open API specification.

Test the OpenAPI definition

Before you use the API definition, it's a good idea to test it in the Azure Functions UI.

  1. On the Manage tab of your function, under Host Keys, copy the default key.

    Copy API key

    Note

    You use this key for testing, and you also use it when you call the API from an app or service.

  2. Go back to the API definition: function-demo-energy > Platform features > API definition.

  3. In the right pane, click Change Authentication, enter the API key that you copied, and click Authenticate.

    Authenticate with API key

  4. Scroll down and click Try this operation.

    Try this operation

  5. Enter values for hours and capacity.

    Enter parameters

    Notice how the UI uses the descriptions from the API definition.

  6. Click Send a request, then click the Pretty tab to see the output.

    Send a request

Next steps

In this tutorial, you learned how to:

  • Create a function in Azure
  • Generate an OpenAPI definition using OpenAPI tools
  • Modify the definition to provide additional metadata
  • Test the definition by calling the function

Advance to the next topic to learn how to create a PowerApps app that uses the OpenAPI definition you created.