Lambda Integration vs. Lambda Proxy: Pros and Cons
Asked Answered
S

6

58

What do you think are the Pros and Cons of using Lambda integration with and without the proxy feature in AWS API Gateway (and more specifically, when using the Serverless framework)? Here's what I think up to now:

Lambda Integration with Proxy

  • Pro: One can rapidly prototype and code without worrying about all the needed configuration details (and reinventing a few wheels like generic template mappings, etc).
  • Pro: It's really easy to return any status code and custom headers, while at the same time there's a generic way to read the body, headers, parameters, of the request.
  • Con: Everything is done in code, so autogenerating documentation is a bit more difficult. Dependencies (headers, models, returned status codes) are "hidden" in the code.

Lambda Integration without Proxy

  • Con: Involves a lot more of work to set it up, and this configuration might be duplicated in different resources.
  • Pro: It allows one to decouple what the lambda receives and returns, and how it gets mapped to different HTTP status codes, headers, and payloads.
  • Pro: Very useful because it stipulates upfront what it returns, and what it requires in terms of headers and payloads.
  • Pro: The hard work when setting up everything is useful in the long run because one can export everything to Swagger, so others can use this to generate different SDKs for it.

What are your thoughts? Do you generally use Lambda Proxy or plain Lambda integrations? What do you prefer, and why?

EDIT: So far, I'm inclined to always choose not to use the proxy features due to the reasons mentioned (decoupling and stating dependencies -headers, status codes, etc- upfront).

Stew answered 26/2, 2017 at 21:6 Comment(1)
Not really sure I agree with your pros and cons and I find this question very interesting and I'd like to see what other people think but opinion-based questions are not what stackoverflow is for.Cami
D
19

(Edit: As noted in the comments, the AWS verbiage I called out in 2018 has been removed. That said, my thoughts regarding Lambda proxy vs. custom integration still hold.)

It looks like AWS recommends choosing Lambda Proxy Integration for new API development.

Note

The Lambda custom integration, formerly known as the Lambda integration, is a legacy technology. We recommend that you use the Lambda proxy integration for any new API. For more information, see Build an API Gateway API with Lambda Proxy Integration

I understand that it's a lot "quicker" (in the short term) to spin up an API endpoint and lambda integration using proxy integration rather than the custom integration, but I'm surprised that it's the recommendation for all API / Lambda development going forward:

  • I pictured API Gateway as being responsible for handling the "HTTP details". Using Proxy Integration forces (at least a subset of) that responsibility onto the Lambda function. (i.e. knowing how to interpret and decide on HTTP headers, query parameters, status codes, etc.)
  • In doing that, I feel that it muddies the responsibility of the backing Lambda function -- Lambda now needs to both handle whatever "business" logic it's being called to do, and also handle interpreting the incoming HTTP values and decide on the outgoing HTTP response values.
  • Granted, you could implement an additional Lambda function layer to abstract away the HTTP details, but isn't that what API Gateway is supposed to do?
  • It reduces the ability to re-use any given Lambda function in a context other than servicing HTTP requests, unless non-HTTP clients format the request as if it were an HTTP request.
Domesticity answered 19/9, 2018 at 13:6 Comment(2)
that verbiage has been removedPollypollyanna
Yes, those words are no longer there, the new one is: "Lambda proxy integration... For many use cases, this is the preferred integration type. " docs.aws.amazon.com/apigateway/latest/developerguide/…Atween
S
4

We also started with Proxy since it really felt fast to get a bunch of functions up and running. Soon it was dawning on us that we created a pretty tight coupling to the way the Proxy forces us to read input and write output and that our function shouldn´t know about this and should have clearer and simpler interfaces. And then we wanted to get started orchestrating a few of those function with AWS Step Functions and that's when we realized we had created functions that really only work with the Proxy integration. Not with Step Functions, and they are certainly not easily migrated away.

No Proxy anymore.

Sammer answered 18/9, 2018 at 14:40 Comment(0)
E
4

Because of body mapping template - proxy is better.

aws api gateway body mapping template dynamodb apache velocity

I do not like body mapping template because in exported Swagger it is escaped, for example:

        uri: "arn:aws:apigateway:us-east-1:dynamodb:action/UpdateItem"
        responses:
          default:
            statusCode: "200"
        requestTemplates:
          application/json: "{\n    \"TableName\": \"happy-marketer\",\n    \"Key\"\
            : {\n        \"pk\": {\n            \"S\": \"project\"\n        },\n \
            \       \"sk\": {\n            \"S\": \"$context.authorizer.claims.email\
            \ $util.urlDecode($input.params('name'))\"\n        }\n    },\n    \"\
            UpdateExpression\": \"SET projectStatus = :c\",\n    \"ExpressionAttributeValues\"\
            : {\n        \":c\": {\n            \"S\": \"Completed\"\n\n        }\n\
            \    }\n}"
        passthroughBehavior: "never"
        httpMethod: "POST"
        type: "aws"
  /projects/{name}/status/restore:
    options:
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - name: "name"
        in: "path"

And as you understand - this is bad to edit such "code" locally and deploy this swagger file. Also when you edit body mapping template in the browser - you will not receive errors about your wrong JSON / Apache Velocity. For example here we have a mistake:

{
  "email": "$context.authorizer.claims.email",
  "nameOld": "$util.urlDecode($input.params('name'))",

  #if ($input.path('$.nameNew') != "")
  "nameNew": "$util.urlDecode($input.path('$.nameNew'))",
  #end

  #if ($input.path('$.ownerNew') != "")
  "ownerNew": "$input.path('$.ownerNew')",
  #end
  
  #if ($input.path('$.shared') != "")
  "shared": $input.json('$.shared')
  #end
  
  #if ($input.path('$.StartDate') != "")
  , "startDate": "$input.path('$.StartDate')"
  #end
  
  #if ($input.path('$.DueDate') != "")
  , "dueDate": "$input.path('$.DueDate')"
  #end
}

The mistake is - wrong , before startDate. My backend code in Go is free from such mistakes. I do not want to write tests for Apache Velocity.

Also, maybe Proxy Integrations are faster - because of missing "service-in-the-middle".

Ectropion answered 1/4, 2020 at 14:16 Comment(0)
A
2

No proxy.

I have several SLS deployments in production, some generating revenue some as internal tools. I exclusively use no proxy. I dont want to rely on the structures of AWS for my application so if we stop being friends I can migrate without too much pain.

As to the Pros of the proxy I would consider them as cons, as it feels you have too and the con as a pro. I've seen it all before "lets move super fast". Yes we need to be agile and move quickly but not at the cost of thinking. I get this with my engineers all the time, its one thing to be low on documentation/design another all together to say "nuts to planning lets just code". Thats how you corner yourself, no matter how fast you get to market. With no proxy (and some early planning to your project structure and maybe some good DDD thinking) its pretty simple to migrate away from AWS should the world burn.

Further to this I find it very difficult to get new bods up to speed with AWS stuff. Once you know it its all gravy but devs are devs, not infrastructure engineers (those of us who do both are surprisingly rare). Abstracting away helps people be productive as they begin their daunting journey down the rabithole. Id rather my coder code than need to bother me about CFN every 20 minutes.

Anatolian answered 21/7, 2017 at 3:40 Comment(2)
non-proxy (custom integration) is actually a lock down to AWS stack, not proxy.Atween
@Atween It depends what part of the code you want to move. Using non-proxy allows the lambda development to remain relatively stack-agnostic. It could be cut and dropped into a completely different service. All of the AWS-specific implementation is hosted in the API Gateway, which performs the request and response mapping to a standardized format. API Gateway could be replaced by a different service which could be programmed to return the same inputs and expect the same outputs from the lambda code.Methodical
A
1

As a matter of best practices I personally would choose the proxy integration (as distinct from a proxy resource). Here's why:

  • VTL is another thing you have to learn if you don't use the proxy integration. Also, how do you test your VTL logic? I would argue that this logic is more business than not. Also, debugging VTL is horrible, in my experience.
  • Having the HTTP response mapping logic in code makes it easily testable. And besides, you can decouple the HTTP response mapping logic easily from the business logic of your endpoints, using an adapter pattern.
Amadeus answered 27/7, 2021 at 21:36 Comment(0)
I
0

Just adding one con, since this caught me by surprise when I started using an RDS proxy. I setup an AWS Lambda with an RDS Proxy and then found out my RDS costs doubled. So, the con, RDS Proxy costs more money, it looks like it doubled my RDS costs. For when the proxy is needed, I'm sure costs are warranted, however, for smaller scale projects, like mine, keeping costs down is important.

The RDS instance is already non public facing and so is protected. Adding the Lambda to the VPC and using security groups worked just fine.

Inverse answered 2/7 at 23:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.