A collection of patterns when developing APIs with AWS Lambda
Tags: serverless, aws, api, lambda
Published: 2020-11-29 12:47:47

#Conclusion
When developing API with AWS Lambda, the following 4 patterns can be considered. Each has its advantages and disadvantages, so I think you will choose based on your requirements and member skill sets.

### ① Functions (separate source) pattern
![functions pattern](https://dev-to-uploads.s3.amazonaws.com/i/um7wx8h7vro5hvko4nxi.png)
 
### ② Functions (same source) pattern
![functions pattern2](https://dev-to-uploads.s3.amazonaws.com/i/las34v3gdyn5rmk5l3vg.png)
 
### ③ Web Framework pattern
![proxy integration pattern](https://dev-to-uploads.s3.amazonaws.com/i/y8xx9lpc3jjpyhe1tqq5.png)
 
### ④ GraphQL pattern
![graphql pattern](https://dev-to-uploads.s3.amazonaws.com/i/f6l9hwnez3r6tvj84ywv.png)
 


#Background
## API development with AWS Lambda
It is possible to develop serverless API by combining AWS Lambda and API Gateway. By building without a server, you can obtain scalability and cost optimization without any hassle, and you can significantly reduce the operation cost because you do not need to monitor life and death.

## Development patterns are not organized
Although serverless API development has many advantages, there are various development patterns and there is no consistent method. For example, Lambda can be deployed by manually uploading a zip, using a deployment support tool such as SAM / Serverlesss Framework, or using the online editor Cloud9. In some cases, the directories are separated for each function, and in other cases, the source code is shared and only the entry point is switched. Furthermore, it can be created not only with REST but also with GraphQL. I couldn't find a document that organized these patterns properly, so I decided to summarize them this time.

#Lambda API development pattern
## ① Functions (separate source) pattern
![functions pattern](https://dev-to-uploads.s3.amazonaws.com/i/08er8r9you8hg3pqbx93.png)
 

### Characteristic
* No resources or source files are shared between Lambda
* Lambda function resources are created as many as the number of API paths
* If there is common logic, put it in Layer
* This pattern will be used when developing with Cloud9

### merit
* Very loosely coupled because there are no dependencies between Lambda. Therefore, you can easily add or modify APIs.
* Since resources are separated, Cloudwatch logs are output for each function, making error logs very easy to follow.
* Since resources are separated for each function, it is possible to create a secure configuration because detailed policies can be set.


### Demerit
* Even if you put the common logic in the layer, you still have trouble with layer version control. Even if you update the layer, the already deployed Lambda functions refer to the old layer, so you have to redeploy all the Lambda functions once.
* The logic placed in the layer does not complement the editor, which reduces development efficiency.
* When using a deployment support tool such as SAM / Serverless Framework, the configuration file (template.yaml / serverless.yaml) tends to be complicated. If you need to pass environment variables to all resources, that alone will increase the number of lines in the config file.
* While fine-grained policy settings for each function are beneficial, they are difficult to manage.

## ② Functions (same source) pattern
![functions pattern2](https://dev-to-uploads.s3.amazonaws.com/i/5k916edbcdfh8du5n90t.png)
 

### Characteristic
* The same source file is used, but resources are separated because the Lambda function is created by switching the entry point (file name / function name) of each Lambda.
* Lambda function resources are created as many as the number of API paths

### merit
* Common logic can be reused without using Layer
* Since resources are separated, Cloudwatch logs are output for each function, making error logs very easy to follow.
* Since resources are separated for each function, you can fine-tune the policy and create a secure configuration.

### Demerit
* Since the source file is shared by each Lambda, it is necessary to consider the range of influence when adding or modifying the API.
* When using a deployment support tool such as SAM / Serverless Framework, the configuration file (template.yaml / serverless.yaml) tends to be complicated. If you need to pass environment variables to all resources, that alone will increase the number of lines in the config file.
* While fine-grained policy settings for each function are beneficial, they are difficult to manage.

## ③ Web Framework pattern
![proxy integration pattern](https://dev-to-uploads.s3.amazonaws.com/i/veoi1wmeax9jfscck37c.png)
 
### Characteristic
* API Gateway passes the received request to Lambda as it is, and the web framework on Lambda performs routing etc.
* API Gateway is an integration with proxy resources. (The path variable will look like / {proxy +})
* You need to use a library that connects the interface between Lambda and Web Framework (eg aws-serverless-express, challice, Serverless Framework Plugin, etc.)

### merit
* If you have knowledge of Web Framework, you can develop without knowledge of Lambda.
* It's just wrapping the web framework in a library, which makes it very easy when you need to move from serverless to EC2 or on-premises.

### Demerit
* Can only be used with web frameworks that support libraries
* It will be a structure that tends to be a monolith
* The size of the deployment package will increase. However, this can be solved by putting the dependent packages on the layer.

## ④ GraphQL pattern
![graphql pattern](https://dev-to-uploads.s3.amazonaws.com/i/denvt1i9h1ax4d0eyxw0.png) 

### Characteristic
* Use [Apollo Server on Lambda] (https://www.apollographql.com/docs/apollo-server/deployment/lambda/) to put the GraphQL server on Lambda.
* GraphQL server looks at the body of the request and handles the query
* API Gateway will be a single endpoint of / graphql

### merit
* You can benefit from GraphQL (query flexibility, agility, performance improvements, PlayGround, automatic type information generation etc ...)
* There is room for adding endpoints to API Gateway, so it can coexist with REST.

### Demerit
* Learning costs are higher because knowledge is less pervasive than REST. I think it is necessary to choose carefully because it will lead to education costs and transfer costs.
* Receives the disadvantages of GraphQL (use of the library is almost mandatory on the client side, etc.)

#Summary

Finally, I would like to compare and summarize each pattern item by item.
## No need to consider the range of influence
Since the functions pattern (source code separation) separates both resources and sources, there are no dependencies, and functions can be added or modified without considering the range of influence. I think that there is a big advantage when developing with multiple members. Other patterns share the source code, so you need to consider a certain extent of influence.

## Detailed policy management
If you have a need to set a policy for each Lambda function, you need to select the functions pattern. This is a security advantage, but it is also a disadvantage that makes management difficult.
In the case of GraphQL pattern, REST API can be added as needed, so if you really need this, you can cut it out and create Lambda and set the policy.

## Use of common logic
If you can share the source code, you can use common logic, but not with the functions pattern (source code separation). You can use common logic with Layer, but I don't think it's a good option given the lack of completion and the cumbersome version control.

## Easy to install
The functions pattern can be started immediately by using the SAM / Serverless Framework, but the other patterns are a little less easy to install because they require the settings of libraries and plugins.

## Migrate to server
If there is a possibility of moving from serverless to EC2 / on-premise from the viewpoint of performance, it is desirable to have a configuration that can quickly remove resources. WebFramework patterns and GraphQL patterns can be moved to on-premise immediately by peeling off the wrapped library.

## Low learning cost
Web Framework patterns that can be developed without being aware of Lambda will be more competitive in terms of learning costs. GraphQL is currently the most costly option to learn.

## Ease of development
The functions pattern (source code separation) is difficult to develop because common logic is difficult to use. WebFramework patterns and GraphQL patterns can benefit from the framework and can be developed without any problems.

## Ease of tracking error logs
When you want to follow the error log after deployment, the functions pattern in which CloudWatch is divided for each resource makes it easy to follow the error log.

## Easy to deploy
The bottleneck of the functions pattern is that the SAM / Serverless Framework configuration file tends to be complicated. WebFramework patterns are grouped into proxies and GraphQL patterns are grouped into a single endpoint, so configuration files can be kept simple.

# Finally
How was that?
The content of this article is basically an experience-based description, so it may not be comprehensive.
We would love to hear your opinions and reflect them in the content.
I would be very happy if you could comment on a story like "I developed this pattern, but it was good here, it was inconvenient here."