首頁 > 後端開發 > Golang > 使用 SAM 框架建置 Go Serverless REST API 並部署到 AWS (Amazon Linux untime)

使用 SAM 框架建置 Go Serverless REST API 並部署到 AWS (Amazon Linux untime)

WBOY
發布: 2024-08-23 06:42:11
原創
859 人瀏覽過

為什麼還要另一個 Go 教程

AWS 最近已棄用多項服務和運行時。正如我們所看到的,隨著我們喜愛的 CodeCommit 和其他關鍵服務的終止,AWS Lambda 函數不再支援 Go1.x。

如果您嘗試部署大部分過時的教學課程,您可能會遇到以下錯誤:

Resource creation Initiated    
CREATE_FAILED                    AWS::Lambda::Function            DemoFunction                     
                                   Resource handler returned message: 
                                   "The runtime parameter of go1.x is no longer supported for 
                                   creating or updating AWS Lambda functions. We recommend you 
                                   use a supported runtime while creating or updating functions. 
                                   (Service: Lambda, Status Code: 400, Request ID:  
                                   81f1f708-0a7a-40d0-8442-b9c16510d01f)" 
ROLLBACK_IN_PROGRESS             AWS::CloudFormation::Stack       lambda-go-gorilla                
                                   The following resource(s) failed to create: 
                                   [DemoFunction]. Rollback requested by user.
登入後複製

關鍵要點是軟體中唯一不變的就是變化。然而,有一些永恆的原則我們應該永遠牢記

為了解決這個問題,我決定建立一個最新的儲存庫,其中包含部署 Go 應用程式所需的所有基礎架構。有兩種選擇:

  1. 使用 Docker 容器透過 Fargate 部署。
  2. 在 AWS 上使用 SAM 框架進行部署。

您可以在 GitHub 上找到儲存庫。

軟體開發中永恆的原則

  • 基礎設施即程式碼至關重要。
  • 軟體中良好的命名約定至關重要。
  • 永遠測試你的邏輯。
  • 可用性和可擴充性
  • 部署管道作為自動化軟體交付流程的機制。
  • 可觀察性是強制性的。
  • 安全性是雲端原生應用程式中的一等公民。
  • Go 是建置 API 的絕佳選擇。

基礎設施即程式碼至關重要

不可變的基礎設施使我們能夠在更高的層面上聲明我們想要什麼,並確保開發和生產環境保持盡可能接近。例如:

CompoundingFunction:
  Type: AWS::Serverless::Function
  Metadata:
    BuildMethod: makefile
  Properties:
    FunctionName: CompoundingFunction
    Architectures: ["arm64"]
    Handler: bootstrap
    Runtime: provided.al2
    CodeUri: ./functions/CompoundingFunction/
    MemorySize: 512
    Timeout: 10
    Environment:
      Variables:
        COMPOUNDING_TABLE_NAME: !Ref CompoundingTable
    Policies:
      - DynamoDBCrudPolicy:
          TableName: !Ref CompoundingTable
    Events:
      ApiGatewayPost:
        Type: Api
        Properties:
          RestApiId: !Ref ApiGateway
          Path: /compounding
          Method: POST
登入後複製

軟體中良好的命名約定是關鍵

如果您有一套好的測試,請不要害怕重構。重構是軟體開發中的重要活動。名稱很重要,因為它們出現在模組、函數、套件、變數等中的任何地方。

package main

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

// Response is the structure for the response JSON
type Response struct {
    Message      string    `json:"message"`
    GainsPerYear []float64 `json:"gainsPerYear"`
}

type Request struct {
    Principal  float64 `json:"principal"`
    AnnualRate float64 `json:"annualRate"`
    Years      int     `json:"years"`
}

func HelloHandler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    var req Request
    err := json.Unmarshal([]byte(event.Body), &req)
    if err != nil {
        return createResponse(400, "Invalid request body")
    }
    fmt.Println("Request", req)
    gainsPerYear := CalculateCompoundInterest(req.Principal, req.AnnualRate, req.Years)
    fmt.Println(gainsPerYear)
    response := Response{
        Message:      "Calculation successful",
        GainsPerYear: gainsPerYear,
    }

    body, err := json.Marshal(response)
    if err != nil {
        return createResponse(500, "Error marshalling response")
    }

    return createResponse(200, string(body))
}

func createResponse(statusCode int, body string) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        StatusCode: statusCode,
        Body:       body,
        Headers:    map[string]string{"Content-Type": "application/json"},
    }, nil
}

func main() {
    lambda.Start(HelloHandler)
}
登入後複製

永遠測試你的邏輯

在無伺服器應用程式中,單元測試很重要,但不要忘記還包括整合測試,因為大多數這些應用程式都依賴整合和策略來解決業務問題。

func TestCalculateCompoundInterest(t *testing.T) {
    principal := 100000000.0
    annualRate := 10.0
    years := 10

    result := CalculateCompoundInterest(principal, annualRate, years)
    lastElement := round(result[len(result)-1], 2)

    expected := round(259374246.01, 2)
    if !reflect.DeepEqual(lastElement, expected) {
        t.Errorf("Expected %v, but got %v", expected, lastElement)
    }
}
登入後複製

可用性和可擴充性

無伺服器架構預設情況下高度可用,並且是事件驅動的,消除了大多數操作任務。但是,如果您選擇依賴 ECS 和容器,那麼包含負載平衡器來在伺服器之間分配流量以確保可用性和可擴展性非常重要。

  CompoundingLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: compounding-nlb
      Scheme: internet-facing
      Type: network
      Subnets:
        - !Ref PublicSubnetOne
        - !Ref PublicSubnetTwo
登入後複製

部署管道

部署管道使軟體交付過程自動化。我們創建了一個 Makefile 來簡化此過程,從而可以使用單一命令輕鬆部署和執行重複任務。這種方法提高了部署工作流程的效率和一致性。

Build Go Serverless REST APIs and Deploy to AWS using the SAM framework (Amazon Linux untime)

可觀察性是強制性的

確保您有追蹤、日誌記錄和指標。對於無伺服器應用程序,啟用這些功能就像添加 Tracing: Active 一樣簡單。在 CloudWatch 等中心位置查看所有日誌並監控服務互動的能力是非常寶貴的。

Build Go Serverless REST APIs and Deploy to AWS using the SAM framework (Amazon Linux untime)

安全性是雲端原生應用程式中的一等公民

安全性在所有應用程式中都是最重要的。使用 Amazon Cognito 提供強大的使用者驗證,而 API 金鑰則添加了額外的控制和授權層,確保只有授權的用戶端才能存取您的 API。

Auth:
  DefaultAuthorizer: CompoundingAuthorizer
  Authorizers:
    CompoundingAuthorizer:
      UserPoolArn:  XXXX
    LambdaTokenAuthorizer:
      FunctionArn: !GetAtt LambdaTokenAuthorizerFunction.Arn
      FunctionPayloadType: REQUEST
      Identity:
        Headers:
          - Authorization
        ReauthorizeEvery: 100
  AddDefaultAuthorizerToCorsPreflight: false
登入後複製

為每個服務、使用者和元件分配最少的必要權限,以減少攻擊面並防止未經授權的存取。 最小特權原則

      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref CompoundingTable
登入後複製

參考

  1. Terraform in Action - 實施 Terraform 的實際用途和策略,Terraform 是用於建置、變更和管理基礎架構的工具。
  2. 持續交付管道

結論

軟體不斷發展,雖然有些工具和實踐會發生變化,但基本原則保持不變。我們需要不可變的基礎架構、CI/CD、良好的命名約定、強大的測試策略、API 的安全性以及應用程式的效率。這就是為什麼我決定以無伺服器方式重新建立這個專案。

現在是成為工程師並透過軟體為社會創造價值的最佳時機。

  • 領英
  • 推特
  • GitHub

如果您喜歡這些文章,請訪問我的部落格 jorgetovar.dev

以上是使用 SAM 框架建置 Go Serverless REST API 並部署到 AWS (Amazon Linux untime)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板