admin管理员组

文章数量:1291013

I am building an API for my web application to interact with a SQL database. The web-app can use the API to do CRUD operations on the database. I am using Azure services for both the API (via Function Apps) and the database (via an Azure SQL server).

In the Azure Function App I created multiple HttpTriggers to do different requests. I am using SQL output bindings in the HttpTrigger to write data to the database. See an example of one of the HttpTriggers for a POST request below:

import { HttpRequest, HttpResponseInit, InvocationContext, output, SqlOutput } from "@azure/functions";

export const postProjectSQLOutput: SqlOutput = output.sql({
    commandText: 'dbo.Projects',
    connectionStringSetting: 'sqlConnectionString'
});

export async function postProject(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log('HTTP trigger and SQL output binding function processed a request.');

    const body = await request.json();
    context.log('Body:', body);

    const project = body[0];

    const parameters = {
        ID: project.id,
        Name: project.name,
        Project_Type: project.type
    };

    try {
        context.extraOutputs.set(postProjectSQLOutput, parameters);
        return { status: 201, jsonBody: 'Project created successfully' };
    } catch (error) {
        context.log('Error:', error);
        return { status: 500, jsonBody: error.message };
    }
};

This trigger works. When it is called and the correct data is provided in the body of the request it will add a record to the database, I have two problems however with this approach for doing POST requests, namely:

  1. I don't get any response from the output binding whether or not the POST operation succeeded. The context.extraOutputs.set() method is a void method so I'm not getting anything back

  2. The HttpTrigger will return a status of 201 regardless of whether the POST operation succeeded, again because the output binding doesn't return anything indicating whether the operation was succesfull.

My question is: How can I get a response from the function to indicate whether or not the operation was succesful? And can I get the newly created record and have it send back to the API?

The documentation Azure SQL Output binding for Azure Fuctions doesn't say anything about a response from the output binding, and I can't find much other documentation on HttpTriggers with output bindings written in TypeScript.

I followed the documentation from Microsoft on the topic for as far as it would go, and managed to get as far as I described above.

I am building an API for my web application to interact with a SQL database. The web-app can use the API to do CRUD operations on the database. I am using Azure services for both the API (via Function Apps) and the database (via an Azure SQL server).

In the Azure Function App I created multiple HttpTriggers to do different requests. I am using SQL output bindings in the HttpTrigger to write data to the database. See an example of one of the HttpTriggers for a POST request below:

import { HttpRequest, HttpResponseInit, InvocationContext, output, SqlOutput } from "@azure/functions";

export const postProjectSQLOutput: SqlOutput = output.sql({
    commandText: 'dbo.Projects',
    connectionStringSetting: 'sqlConnectionString'
});

export async function postProject(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log('HTTP trigger and SQL output binding function processed a request.');

    const body = await request.json();
    context.log('Body:', body);

    const project = body[0];

    const parameters = {
        ID: project.id,
        Name: project.name,
        Project_Type: project.type
    };

    try {
        context.extraOutputs.set(postProjectSQLOutput, parameters);
        return { status: 201, jsonBody: 'Project created successfully' };
    } catch (error) {
        context.log('Error:', error);
        return { status: 500, jsonBody: error.message };
    }
};

This trigger works. When it is called and the correct data is provided in the body of the request it will add a record to the database, I have two problems however with this approach for doing POST requests, namely:

  1. I don't get any response from the output binding whether or not the POST operation succeeded. The context.extraOutputs.set() method is a void method so I'm not getting anything back

  2. The HttpTrigger will return a status of 201 regardless of whether the POST operation succeeded, again because the output binding doesn't return anything indicating whether the operation was succesfull.

My question is: How can I get a response from the function to indicate whether or not the operation was succesful? And can I get the newly created record and have it send back to the API?

The documentation Azure SQL Output binding for Azure Fuctions doesn't say anything about a response from the output binding, and I can't find much other documentation on HttpTriggers with output bindings written in TypeScript.

I followed the documentation from Microsoft on the topic for as far as it would go, and managed to get as far as I described above.

Share Improve this question asked Feb 13 at 16:31 FrankFrank 112 bronze badges 1
  • Use an SQL input binding to query the inserted record after setting the output binding, or switch to direct SQL execution with OUTPUT INSERTED.* to get an immediate response. – Dasari Kamali Commented Feb 14 at 3:34
Add a comment  | 

1 Answer 1

Reset to default 0

I tried the below code, which waits for the insert operation using setTimeout(1000), then retrieves the last inserted record through SQL input binding to confirm success. It fetches and returns the inserted record, providing verification and response to the HTTP trigger Function.

httpTrigger1.ts :

import { app, HttpRequest, HttpResponseInit, InvocationContext, output, SqlOutput, input, SqlInputOptions } from "@azure/functions";

const sqlOutput: SqlOutput = output.sql({
    commandText: "dbo.Projects", 
    connectionStringSetting: "SqlConnectionString"
});

const sqlInput = input.sql({
    commandText: "SELECT TOP 1 * FROM dbo.Projects ORDER BY ID DESC",
    commandType: "Text", 
    connectionStringSetting: "SqlConnectionString"
} as SqlInputOptions);  

export async function postProject(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log("Processing request...");

    try {
        const body = await request.json();
        context.log("Received Body:", body);
        let projects = Array.isArray(body) ? body : [body];
        if (projects.length === 0) {
            return { status: 400, jsonBody: { message: "Invalid request body" } };
        }

        const outputData = projects.map(project => ({
            ID: project.ID,
            Name: project.Name,
            Project_Type: project.Project_Type
        }));

        context.extraOutputs.set(sqlOutput, outputData);
        await new Promise(resolve => setTimeout(resolve, 1000));
        const insertedRecord = (await context.extraInputs.get(sqlInput)) as any[];

        return {
            status: 201,
            jsonBody: {
                message: "Project inserted successfully",
                insertedProject: insertedRecord?.length ? insertedRecord[0] : null
            }
        };
    } catch (error) {
        context.log("Error:", error);
        return { status: 500, jsonBody: { error: error.message } };
    }
}

app.http("postProject", {
    route: "post-project",
    methods: ["POST"],
    authLevel: "anonymous",
    extraOutputs: [sqlOutput],
    extraInputs: [sqlInput],  
    handler: postProject
});

local.settings.json :

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<storageConnString>",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "SqlConnectionString": "<SQLConneString>"
  }
}

I have successfully sent a POST request using the HTTP trigger function in TypeScript through Postman.

http://localhost:7071/api/post-project
{
  "ID": 5,
  "Name": "Azure Project",
  "Project_Type": "Cloud"
}

Output :

本文标签: typescriptReturning the result of an output bindingStack Overflow