serverless-express icon indicating copy to clipboard operation
serverless-express copied to clipboard

How is Azure Functions support going on?

Open maciejkulinski opened this issue 4 years ago • 3 comments

Hello, thank you for your great work!

I'm currently using v3 with Azure Functions and I would love to move to v4.

I've been looking at azure/init branch and I'm very keen to see it finding its way onto mainline.

What's the timeline for Azure Functions support?

maciejkulinski avatar Feb 16 '21 11:02 maciejkulinski

Hey! I got Serverless Express working on Azure with that branch but with limited testing. I'm not too familiar with Azure so the example probably could do with some improvements. I could merge this info mainline and label Azure support as experimental.

How'd you manage to get V3 working with Azure?

brettstack avatar Feb 16 '21 13:02 brettstack

This is my setup with v3. Works great apart from the issue with headers size. This is the only reason I'm looking at v4 - #248. My current setup is locked to Node 12 and I have no ability to specify max-http-header-size flag.

import { Context, HttpRequest } from '@azure/functions';
import express, { Express, Request as ExpressRequest } from 'express';
import ServerlessExpress from 'aws-serverless-express';
import { APIGatewayProxyEvent, Context as FunctionContext } from 'aws-lambda';
import url from 'url';

const AzureFunctionHandler = function (app: Express) {
  const binaryTypes = ['*/*'];

  const server = ServerlessExpress.createServer(app, undefined, binaryTypes);

  return (context: Context, req: HttpRequest) => {
    const customAuthorization = req.headers['x-custom-authorization'];
    delete req.headers['x-custom-authorization'];
    /* eslint-disable no-unneeded-ternary */
    req.headers.authorization = customAuthorization ? customAuthorization : '';

    const path = url.parse((req as ExpressRequest).originalUrl).pathname;

    const event: APIGatewayProxyEvent = {
      path,
      pathParameters: null,
      httpMethod: req.method,
      headers: req.headers || {},
      queryStringParameters: req.query || {},
      body: req.rawBody,
      isBase64Encoded: false,
      multiValueHeaders: {},
      multiValueQueryStringParameters: null,
      stageVariables: null,
      requestContext: null,
      resource: null,
    };

    const azureContext: FunctionContext = {
      callbackWaitsForEmptyEventLoop: false,
      functionName: '',
      functionVersion: '',
      invokedFunctionArn: '',
      memoryLimitInMB: '',
      awsRequestId: '',
      logGroupName: '',
      logStreamName: '',
      getRemainingTimeInMillis: () => 0,
      succeed(expressResponse: any) {
        if (expressResponse.statusCode !== 200) {
          context.log(
            `Error: ${expressResponse.statusCode}: ${expressResponse.body}`,
          );
          context.res.status = expressResponse.statusCode;
          context.res.headers = {
            ...context.res.headers,
            ...expressResponse.headers,
          };
          context.res.body = Buffer.from(
            expressResponse.body,
            expressResponse.isBase64Encoded ? 'base64' : 'utf8',
          );
          context.res.isRaw = true;
        } else {
          context.res.status = expressResponse.statusCode;
          context.res.headers = {
            ...context.res.headers,
            ...expressResponse.headers,
          };
          context.res.body = Buffer.from(
            expressResponse.body,
            expressResponse.isBase64Encoded ? 'base64' : 'utf8',
          );
          context.res.isRaw = true;
        }

        context.done();
      },
      done: () => {},
      fail: () => {
        context.log('fail');
      },
    };
    ServerlessExpress.proxy(server, event, azureContext);
  };
};

const app = express();

export default AzureFunctionHandler(app);

maciejkulinski avatar Feb 16 '21 14:02 maciejkulinski

Any progress after 1 year? :)

gotexis avatar Mar 27 '22 00:03 gotexis

@gotexis I added Azure support at the end of 2021 but it took some time until it got merged but it is available since April 2022.

@brettstack I think you can close this issue?

Shamshiel avatar Aug 18 '22 08:08 Shamshiel

Thanks again @Shamshiel

brettstack avatar Aug 19 '22 05:08 brettstack