- Đăng vào
HTML Reader với Golang và Lambda function
- Tác giả
- Name
- Anh Cloud
- @vntechies.cloud
Mục lục
Repository của hướng dẫn này có tại đây
Trong bài viết này, chúng ta sẽ xem xét cách triển khai bất kỳ hàm Golang nào lên AWS Lambda một cách siêu dễ dàng. Chúng ta có thể chạy hầu như tất cả các loại ứng dụng, back end service với zero administration (không cần quản lý)
Vậy thì chúng ta sẽ làm gì?
Chúng ta sẽ phát triển một html reader tương tự với reader mode trên các trình duyệt web hiện tại. Chọn ảnh hơi cay nhé ông bạn 🥲
Thiết kế
Hệ thống với yêu cầu đơn giản nên chúng ta cũng sẽ có diagram đơn giản. Flow:
- Người dùng truy cập vào html reader với params url là địa chỉ của trang muốn đọc
- Lambda function sẽ get html code, parse và format lại nội dung chính bằng thư viện go-readability1
- Trả HTML nội dung chính được xử lý tại Lambda fucntion
Triển khai
SAM local
- Cài đặt SAM CLI
- Tạo project go-reader
sam init --name go-reader --runtime go1.x
- Cài đặt AWS credentials
vi ~/.aws/credentials
[vntechies]
aws_access_key_id=******
aws_secret_access_key=******
- Tạo template cho hệ thống sử dụng SAM
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
go-reader
Sample SAM Template for go-reader
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
Resources:
GoReaderFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: go-reader/
Handler: handler
Runtime: go1.x
Architectures:
- x86_64
Events:
CatchAll:
Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /
Method: GET
ApiId: !Ref GoReaderHTTPApi
GoReaderHTTPApi:
Type: AWS::Serverless::HttpApi
Properties:
CorsConfiguration:
AllowOrigins:
- "*"
AllowHeaders:
- "Content-Type"
- "Access-Control-Allow-Origin"
- "Access-Control-Allow-Headers"
AllowMethods:
- GET
- OPTIONS
Outputs:
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
GoReaderAPI:
Description: "API Gateway endpoint URL for Prod environment for First Function"
Value: !Sub "https://${GoReaderHTTPApi}.execute-api.${AWS::Region}.amazonaws.com/"
GoReaderFunction:
Description: "First Lambda Function ARN"
Value: !GetAtt GoReaderFunction.Arn
GoReaderFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt GoReaderFunction.Arn
Một số lưu ý
- Lambda function connect được với public Internet by default
AWS::Serverless::HttpApi
sử dụng HTTP API thay vì REST API vì chỉ cần Regional access và không cần những tính năng của REST API -> giảm chi phí- AllowHeaders
Content-Type
lambda function sẽ serve html code và trả về cho người dùng thông qua API gateway, API Gateway cần phải truyền headers này tới user, nếu không browser sẽ hiển thị response dưới dạng text thay vì html code.
Hàm Lambda cho GoReader
- Sau khi lấy được nội dung chính của trang web qua url người dùng cung cấp, chúng ta sẽ format lại sử dụng thư viện bamboo css2
package main
import (
"errors"
"time"
readability "github.com/go-shiori/go-readability"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
var (
ErrNoURL = errors.New("No URL provided")
)
func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
url := request.QueryStringParameters["url"]
if len(url) <= 0 {
return events.APIGatewayProxyResponse{}, ErrNoURL
}
article, err := readability.FromURL(url, 30*time.Second)
if err != nil {
return events.APIGatewayProxyResponse{}, err
}
html := "<!DOCTYPE html><html><head><meta charset='utf-8'/><title>GO READER</title><meta name='viewport' content='width=device-width, initial-scale=1'/><link rel='stylesheet' href='https://unpkg.com/bamboo.css'/></head><body><h2 id='title'>" + article.Title + "</h2><h4>" + article.Excerpt + "</h4><p id='output'>" + article.Content + "</p></body></html>"
return events.APIGatewayProxyResponse{
StatusCode: 200,
Headers: map[string]string{
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "origin,Accept,Authorization,Content-Type",
"Content-Type": "text/html; charset=utf-8",
},
Body: html,
IsBase64Encoded: false,
}, nil
}
func main() {
lambda.Start(handler)
}
- Cài đặt cách thư viện cần thiết trước khi đóng build và đóng gói hàm
cd go-reader
go get github.com/go-shiori/go-readability
Test & Validate & Build & Deploy
# test function bằng event mẫu từ APIGW
sam local invoke "GoReaderFunction" -e events/error_event.json
sam local invoke "GoReaderFunction" -e events/event.json
# validate SAM template
sam validate --profile vntechies --region ap-southeast-1
# build package
sam build
# deploy
sam deploy --guided --profile vntechies
Sản phẩm
Kết luận: Như 2 giọt nước 🤣
Với việc support nhiều ngôn ngữ và có thể nhanh chóng, dễ dàng triển khai một dịch vụ mới, Lambda là một lựa chọn tốt cho các stack công nghệ phát triển với Golang.
VNTechies Dev Blog
Kho tài nguyên mã nguồn mở với sứ mệnh đào tạo kiến thức, định hướng nghề nghiệp cho cộng đồng Cloud ☁️ DevOps 🚀
Tham gia group VNTechies - Cloud ☁️ / DevOps 🚀 nếu bạn muốn giao lưu với cộng đồng và cập nhật các thông tin mới nhất về Cloud và DevOps.
- Website: https://vntechies.dev
- Github repository: https://github.com/vntechies
- Facebook page: https://facebook.com/vntechies
Anh chị em hãy follow/ủng hộ VNTechies để cập nhật những thông tin mới nhất về Cloud và DevOps nhé!