「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Go サーバーレス REST API を構築し、SAM フレームワーク (Amazon Linux untime) を使用して AWS にデプロイする

Go サーバーレス REST API を構築し、SAM フレームワーク (Amazon Linux untime) を使用して AWS にデプロイする

2024 年 9 月 18 日に公開
ブラウズ:580

別の Go チュートリアルを使用する理由

AWS は最近、いくつかのサービスとランタイムを非推奨にしています。私たちが愛する CodeCommit やその他の重要なサービスの廃止で見られたように、Go1.x は AWS Lambda 関数でサポートされなくなりました。

古いチュートリアルのほとんどをデプロイしようとすると、次のようなエラーが発生する可能性があります:

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 アプリケーションのデプロイに必要なすべてのインフラストラクチャを備えた最新のリポジトリを作成することにしました。利用可能なオプションは 2 つあります:

  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 を作成し、反復的なタスクを 1 つのコマンドで簡単にデプロイして実行できるようにしました。このアプローチにより、導入ワークフローの効率と一貫性が向上します。

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 の実際 - インフラストラクチャの構築、変更、管理のためのツールである Terraform を実装するための実践的な使用法と戦略。
  2. 継続的デリバリー パイプライン

結論

ソフトウェアは常に進化しており、一部のツールや手法は変更されますが、基本的な原則は変わりません。不変のインフラストラクチャ、CI/CD、適切な命名規則、堅牢なテスト戦略、API のセキュリティ、アプリケーションの効率が必要です。そのため、このプロジェクトをサーバーレスな方法で再作成することにしました。

エンジニアになってソフトウェアを通じて社会に価値を生み出すには、今ほど良い時期はありません。

  • リンクトイン
  • ツイッター
  • GitHub

記事を気に入っていただけましたら、私のブログ jorgetovar.dev をご覧ください

リリースステートメント この記事は次の場所に転載されています: https://dev.to/aws-builders/build-go-serverless-rest-apis-and-deploy-to-aws-using-the-sam-framework-amazon-linux-2- runtime- 4n5p?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3