DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Low-Code Development: Leverage low and no code to streamline your workflow so that you can focus on higher priorities.

DZone Security Research: Tell us your top security strategies in 2024, influence our research, and enter for a chance to win $!

Launch your software development career: Dive head first into the SDLC and learn how to build high-quality software and teams.

Open Source Migration Practices and Patterns: Explore key traits of migrating open-source software and its impact on software development.

Related

  • Serverless at Scale
  • Building Powerful AI Applications With Amazon Bedrock: Enhanced Chatbots and Image Generation Use Cases
  • How To Get Cell Data From an Excel Spreadsheet Using APIs in Java
  • Migrating MuleSoft System API to AWS Lambda (Part 1)

Trending

  • How to Submit a Post to DZone
  • DZone's Article Submission Guidelines
  • Spring AI: How To Write GenAI Applications With Java
  • Integration Testing With Keycloak, Spring Security, Spring Boot, and Spock Framework
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. How Do I Run My Go Applications in a Serverless Way - Part 2

How Do I Run My Go Applications in a Serverless Way - Part 2

Learn how to take a URL shortener application written using Gin and run it as a serverless AWS Lambda function.

By 
Abhishek Gupta user avatar
Abhishek Gupta
DZone Core CORE ·
Aug. 01, 23 · Tutorial
Like (2)
Save
Tweet
Share
7.6K Views

Join the DZone community and get the full member experience.

Join For Free

The first part of this series introduced you to the AWS Lambda Go API Proxy, and how its framework/package-specific adapter implementations (for gorilla/mux, echo and net/http) allows you to run existing Go applications as AWS Lambda functions fronted by Amazon API Gateway. If you haven't already, I encourage you to take a look at it in order to get a basic understanding of the AWS Lambda Go API Proxy.

The AWS Lambda Go API Proxy also supports Gin, which is one of the most popular Go web frameworks! This follow-up blog post will demonstrate how to take an existing URL shortener service written using the Gin framework and run it as a serverless AWS Lambda function. Instead of using AWS SAM, we will change things up a bit and use the AWS CDK to deploy the solution.

The code is available on GitHub

How Does the Gin Adapter for AWS Lambda Go API Proxy Work?

The aws-lambda-go-api-proxy package makes it possible to run Go APIs written using Gin, thanks to the framework-specific adapter implementations.

Serverless URL shortner


To understand this, let's look into the main.go file of the Lambda function:

Go
 
var ginLambda *ginadapter.GinLambda

func init() {
    r := gin.Default()

    r.POST("/app", CreateShortURL)
    r.GET("/app/:shortcode", GetShortURL)
    r.DELETE("/app/:shortcode", DeleteShortURL)
    r.PUT("/app/:shortcode", UpdateStatus)

    ginLambda = ginadapter.New(r)
}

func Handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    return ginLambda.ProxyWithContext(ctx, req)
}

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


  • In the initfunction:
    • We use gin.Default() to create a gin.Engine object with the Logger and Recovery middleware already attached.
    • We create routes by associating a gin.HandlerFunc with each HTTP method and path using the POST, GET, DELETE and PUT methods of the gin.Engine object.
    • ginadapter.New function takes this *gin.Engine object and returns a ginadapter.GinLambda.
  • In the Handlerimplementation:
    • The Proxy (or ProxyWithContext) method of the ginadapter.GinLambda object receives the events.APIGatewayProxyRequest, converts it into a http.Request object, and sends it to the gin.Engine for routing.
    • It returns a proxy response object (events.APIGatewayProxyResponse) generated from the data written to the response writer (http.ResponseWriter).

Application Overview

The sample application presented in this blog is a trimmed-down version of bit.ly or other solutions you may have used. It uses Amazon DynamoDB for persistence and exposes HTTP endpoints to access the application (basic CRUD operations).

Although we will not be discussing the application code in detail, it's important to understand the basic structure. Here is the package structure for the URL shortener application (in the function directory):

Shell
 
.
├── db
│   └── db.go
├── go.mod
├── go.sum
├── handler.go
├── main.go


  • The db package contains code to interact with DynamoDB.
  • The handler.go file has the implementation for the HTTP methods.
  • The main.go file creates the Gin engine with the routes and ginadapter.GinLambda object to proxy requests and responses.

It's time to deploy the URL shortener application and give it a go!

Pre-requisites

Before you proceed, make sure you have the Go programming language (v1.18 or higher) and AWS CDK installed.

Clone the GitHub repository and change to the right directory:

Shell
 
git clone https://github.com/build-on-aws/golang-gin-app-on-aws-lambda
cd golang-gin-app-on-aws-lambda


Use AWS CDK To Deploy the Solution

AWS CDK is a framework that lets you define your cloud infrastructure as code in one of its supported programming and provision it through AWS CloudFormation. In this case, we will be using the Go bindings for AWS CDK

You can refer to the code in the cdk directory.

To start the deployment, invoke the cdk deploy command. You will see a list of resources that will be created and will need to provide your confirmation to proceed.

Shell
 
cd cdk

cdk deploy

# output

Bundling asset LambdaGolangProxyAPIDemoStack/gin-go-lambda-function/Code/Stage...

✨  Synthesis time: 5.94s

This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

//.... omitted

Do you wish to deploy these changes (y/n)? y


Enter y to start creating the AWS resources required for the application. This will start creating the AWS resources required for our application.

If you want to see the AWS CloudFormation template which will be used behind the scenes, run cdk synth and check the cdk.out folder

You can keep track of the progress in the terminal or navigate to the AWS console: CloudFormation > Stacks > LambdaGolangProxyAPIDemoStack

Once all the resources are created, you can try out the application. You should have:

  • An API Gateway REST API.
  • A Lambda function.
  • A DynamoDB table to store application data.
  • And a few other components (like IAM roles etc.).


LambdaGolangProxyAPIDemoStack


Try the URL Shortener Application

You will need the API Gateway endpoint to invoke with the application - it's available as part of the stack output (in the terminal or the Outputs tab in the AWS CloudFormation console for your stack). It should look something like this - https://foobarbazl.execute-api.us-east-1.amazonaws.com/prod/

1. Start by Generating a Short Code

To generate a short code, you need to pass the original URL in the payload body as part of a HTTP POST request (for e.g. https://abhirockzz.github.io/)

Shell
 
# e.g. export URL_SHORTENER_APP_URL=https://foobarbazl.execute-api.us-east-1.amazonaws.com/prod/app
export URL_SHORTENER_APP_URL=<replace with API Gateway endpoint above>/app

# invoke the endpoint to create short code
curl -i -X POST -d '{"url":"https://abhirockzz.github.io/"}' $URL_SHORTENER_APP_URL
curl -i -X POST -d '{"url":"https://abhishek1987.medium.com/"}' $URL_SHORTENER_APP_URL
curl -i -X POST -d '{"url":"https://dzone.com/users/456870/abhirockzz.html"}' $URL_SHORTENER_APP_URL


If all goes well, you should get a HTTP 201 along with the shortcode in the HTTP response (as a JSON payload).

Shell
 
HTTP/2 201 
content-type: text/plain; charset=utf-8
content-length: 25
apigw-requestid: VTzPsgmSoAMESdA=

{"short_code":"1ee3ad1b"}


Check the DynamoDB table to verify records with the shortcode with the corresponding URL.

DynamoDB table records


2. Access the URL Using the Shortcode

The access link will have the following format - <URL_SHORTENER_APP_URL>/app/<generated short code> for e.g. https://8zbqx074rl.execute-api.us-east-1.amazonaws.com/prod/app/4b824fad

Once you navigate to the link using a browser, you will be automatically redirected to the original URL that you had specified. To better understand what's going on behind the scenes, try accessing the same URL with curl

Shell
 
curl -i $URL_SHORTENER_APP_URL/app/1ee3ad1b


You should get a HTTP 302 response (Found) and the URL redirection happens due to the Location HTTP header which has the original URL.

Shell
 
# some of the headers omitted for brevity
HTTP/2 302 
content-type: application/json
content-length: 0
location: https://abhirockzz.github.io/
....


3. Disable a Short Code

You can disable (and enable) the shortcodes. The original URL will only be accessible if the association is in an active state.

To disable a short code:

Shell
 
export URL_SHORTENER_APP_URL=<replace with API Gateway endpoint above>/app
curl -i -X PUT -d '{"active": false}'  -H 'Content-Type: application/json' $URL_SHORTENER_APP_URL/3626fb51


This is a HTTP PUT request with a JSON payload that specifies the status (false in this case refers to disable action) along with the short code which is a path parameter to the API Gateway endpoint. If all works well, you should see an HTTP 204 (No Content) response.

Check the corresponding record in DynamoDB - the active attribute should have switched to false.

4. Delete a Short Code

Shell
 
export URL_SHORTENER_APP_URL=<replace with API Gateway endpoint above>/app

curl -i -X DELETE $URL_SHORTENER_APP_URL/<short code>


Just like in the case of an update, you should get a HTTP 204 response. But this time, the respective DynamoDB record will be deleted.

We covered the basic operations for the URL shortener application. As an exercise, try out the following scenarios and check the response(s):

  • Access a disabled URL.
  • Enable a disabled URL (use {"active": true}).
  • Access an invalid short code (that does not exist).

Clean Up

Once you're done, to delete all the services, simply use:

Shell
 
cdk destroy


Conclusion

In this blog post, you took a URL shortener application built using the Gin framework and deployed it as a Lambda function. Although this was a simple example, the same approach can be used to deploy more complex applications. As long as you have a reasonable separation of concerns and your application is modular, most of the work will involve refactoring parts of the logic (main.go in this case) to wire up the Gin router (gin.Engine) to a Lambda function handler (entry point) by using the adapter implementation for Gin.

Happy Building!

API AWS AWS Lambda Amazon DynamoDB applications Go (programming language) Short Code (computer language) Data Types

Published at DZone with permission of Abhishek Gupta, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Serverless at Scale
  • Building Powerful AI Applications With Amazon Bedrock: Enhanced Chatbots and Image Generation Use Cases
  • How To Get Cell Data From an Excel Spreadsheet Using APIs in Java
  • Migrating MuleSoft System API to AWS Lambda (Part 1)

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: