dherault / serverless-offline

Emulate AWS λ and API Gateway locally when developing your Serverless project
MIT License
5.19k stars 796 forks source link

Go Lambda broken for non-ApiGateway handlers with custom request/response types (e.g AppSync) #1677

Open seanvm opened 1 year ago

seanvm commented 1 year ago

Bug Report

Current Behavior

When mounting the handler code directly (e.g. not passing --useDocker) the app will fail to run if the handler function signature is not one of the expected ApiGateway request structs.

It looks like support was added last year by @icarus-sullivan via #1320 using https://github.com/icarus-sullivan/mock-lambda for wrapping the lambda.Start function. The version included in serverless-offline seems to have a strict requirement for what the handler function signature should look like:

    if authorizer != "true" {
        response = api(h.(func(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)))
    }

    if authorizer == "true" && tokenAuthorizer == "true" {
        response = token(h.(func(request events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error)))
    }

    if authorizer == "true" && requestAuthorizer == "true" {
        response = request(h.(func(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error)))
    }

However, a lambda function may have a custom request or response type - this is particularly true if the Lambda function is being used with Appsync. As a result the app will fail to run due to an interface conversion error:

panic: interface conversion: interface {} is func(context.Context, map[string]interface {}) (app.User, error), not func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)

Sample Code

Example from aws: https://docs.aws.amazon.com/lambda/latest/dg/golang-handler.html

package main

import (
        "fmt"
        "context"
        "github.com/aws/aws-lambda-go/lambda"
)

type MyEvent struct {
        Name string `json:"name"`
}

func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
        return fmt.Sprintf("Hello %s!", name.Name ), nil
}

func main() {
        lambda.Start(HandleRequest)
}

Expected behavior/code

serverless-offline should support handlers with custom request/response types

Environment

Additional context/Screenshots

oris-sportify commented 6 months ago

Bumping this, currently running serverless offline with go and and api gateway v2 does not work and produces the following error : panic: interface conversion: interface {} is func(context.Context, events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error), not func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)