次.JSとAWSイメージデモ-パート2


このポストがかなり長くなって、私は現在AWSサービスセットアップをここで使用するためにウェブサイトを更新しているパート3を加えます.あなたが既にそのポストに言及するように、ウェブサイトのためにpart 1をすでに読んでいないならば、そのメモで.
第2部では、AWSで必要なサービスを設定します.
画像を記憶するための
  • S 3バケット
  • イメージを検索するためのラムダ関数
    ラムダ機能にアクセスするために
  • APIゲートウェイ終点(自動的に加えられます)
    APIエンドポイントとバケツセットアップのために、私はServerless framework .
    ここでのサービスの設定はフロントエンドのフレームワークで使用できます.私はちょうど反応/次を使用するために窒息しました.js

    サーバーレスセットアップ
    まず、プロジェクトのルートにサーバーフォルダを追加します
    mkdir server && cd server
    
    次にサーバレスセットアップコマンドを実行します.
    serverless
    
    Serverlessオプションをご案内します
    Serverless: No project detected. Do you want to create a new one? Yes
    Serverless: What do you want to make? AWS Node.js
    Serverless: What do you want to call this project? dlw-nextjs-image-demo
    
    Project successfully created in 'dlw-nextjs-image-demo' folder.
    
    You can monitor, troubleshoot, and test your new service with a free Serverless account.
    
    Serverless: Would you like to enable this? No
    You can run the “serverless” command again if you change your mind later.
    
    Serverless: Would you like the Framework to update automatically? Yes
    
    Auto updates were succesfully turned on.
    You may turn off at any time with "serverless config --no-autoupdate"
    
    完全であるとき、Serverlessがあります.サーバディレクトリのYML.デフォルトでは、ファイルには、さまざまなサービスが含まれています.すべてのコメントアウトコードを削除することができますので、各サービスのコードを追加することを通してあなたを歩いていきます.次のようにしてください.
    service: dlw-nextjs-aws-image-demo
    # app and org for use with dashboard.serverless.com
    #app: your-app-name
    #org: your-org-name
    
    # You can pin your service to only deploy with a specific Serverless version
    # Check out our docs for more details
    frameworkVersion: '2'
    
    provider:
      name: aws
      runtime: nodejs12.x
    
    functions:
      hello:
        handler: handler.hello
    
    ただし、実行時にステージと領域を追加するには、次のオプションを選択します.
    provider:
      name: aws
      runtime: nodejs12.x
      stage: dev
      region: eu-west-2
    
    ステージは我々のバケツ名の一部として使われます、そして、私が英国に拠点を置くので、私はロンドンかアイルランドを使います.この例ではロンドンを選びました.

    S 3バケット
    S 3バケットを設定するには、変数を介して参照できるカスタムプロパティを追加します.フレームワークの下に次のように追加します.
    custom:
      upload: blog-nextjs-image-demo
    
    IAMを使用して必要なアクセス許可を追加する必要があります.領域の下に次のiamroleステートメントを追加します.
    provider:
      name: aws
      runtime: nodejs12.x
      stage: dev
      region: eu-west-2
    
      iamRoleStatements:
        - Effect: Allow
          Action:
            - s3:ListBucket
          Resource: "arn:aws:s3:::${opt:stage, self:provider.stage, 'dev'}-${self:custom.upload}"
        - Effect: Allow
          Action:
            - s3:GetObject
          Resource: "arn:aws:s3:::${opt:stage, self:provider.stage, 'dev'}-${self:custom.upload}/*"
    
    インデントは重要です、iamrolestatmentsインデントは、領域に一致する必要があります.IamroleStatement設定は、指定されたリソースに対してアクションが許可されているAWSを指示します.説明を参照
    次に、Serverlessの末尾に次のリソースを追加します.YSL
    resources:
      Resources:
        S3BucketOutputs:
          Type: AWS::S3::Bucket
          Properties:
            BucketName: "${opt:stage, self:provider.stage, 'dev'}-${self:custom.upload}"
    
    バケット名は、指定された変数によって決まります{ opt : stage , self : provide . stage、' dev '}は、例えばsls - deploy -- stage prodからself : providerを実行したときに展開するフラグで決まる.番目のパラメータが使用されていない場合、ステージはprodです.
    $ self :カスタムアップロード}が提供されるカスタムプロパティから取得されます.デモについては、私はフラグを供給していないdevのブログのnextjsイメージのバケツ名の結果
    S 3バケットでは、次のコマンドを実行します.
    sls deploy
    
    配備されたバケットを見るためにAWSコンソールに飛び越してください
    https://s3.console.aws.amazon.com/s3/
    アムスラムダ
    我々は現在、ウェブサイト上に表示するために画像を取得するためにいくつかのラムダ関数を追加する必要があります.このためには、2つのプラグインが必要になります.
    plugins:
      - serverless-bundle # Package our functions with Webpack
      - serverless-dotenv-plugin
    
    次にプラグインをインストールする
    npm i serverless-bundle serverless-pseudo-parameters serverless-dotenv-plugin
    
    Serverlessバンドルによって、ES 2015(およびより新しい)JS構文を書くことができます.そして、それは適切にモジュール輸出/輸入において、それから適切にAWSラムダにバンドルされます.Serverless Dotenvプラグインを使用すると、変数を格納することができます.envファイルが.

    プリURL
    我々のバケツを秘密にしておくために、私は予め署名されたURLを使うつもりです.プリサインされたURLは、バケツで我々のオブジェクトへの一時的なパブリックアクセスを許します.しかし、私はプリサインされたURLを誰にも我々のオブジェクトにアクセスすることができないので、API終点を確保するためにAPIキーを加えます.このアンダーカスタムでは、Dotenvプロパティを追加します
    custom:
      upload: blog-nextjs-image-demo
      dotenv:
        path: ../.env
    
    を追加します.プロジェクトのルートのenvファイル.次のキーを追加します.
    API_KEY=your_api_key
    
    今、我々は最終的に我々の機能を書くことができます.置換
    functions:
      hello:
        handler: handler.hello
    
    関数コードを使用します.
    functions:
      signedUrl:
        handler: handler.signedUrl
        events:
          - http:
              path: signed-url
              method: get
              cors: true
    
    我々のハンドラ関数はSigneDurlと呼ばれ、ウェブサイトからのパス署名URLにGETリクエストを使用します.しかし、私が次を使用しているので、私は を許すためにCORSを指定します.JSはGetServerSidePropsを使用しているので、リクエストはクライアントのブラウザから来ません.したがって、Corsは問題ではありません.クライアント側のみのウェブサイトには、Corsが必要です.
    今すぐオープンハンドラ.jsとすべてのサンプルコードを削除します.AWS SDKにインポートを追加する
    import { S3 } from 'aws-sdk';
    
    私はオブジェクト破壊を使用して、私が必要とするすべてのものとしてAWS SDKからS 3オブジェクトを引っ張ります.ノードのプロセス環境変数から取得するバケツ名への参照を追加します.
    const Bucket = process.env.BUCKET_NAME;
    
    ハンドラ関数の追加
    export const signedUrl = async (event) => {
      // if (event.headers['X-API-KEY'] !== process.env.API_KEY) {
      //   return {
      //     statusCode: 403
      //   };
      // }
    
      const { key } = event.queryStringParameters;
      const s3 = new S3({});
      const presignedGetUrl = await s3.getSignedUrl('getObject', {
        Bucket,
        Key: key,
        Expires: 60 * 5 // time to expire in seconds 5
      });
    
      return {
        statusCode: 200,
        headers: {
          "Access-Control-Allow-Origin": 'http://localhost:3000',
          "Access-Control-Allow-Headers": "*",
          "Access-Control-Allow-Methods": "*",
          "Access-Control-Allow-Credentials": true,
        },
        body: JSON.stringify(presignedGetUrl),
      };
    };
    
    今のところ、APIキーをチェックアウトして、ロックされずにテストできるようにしました.最初にクエリのパラメータからイメージキーを取得します.
    const { key } = event.queryStringParameters;
    
    次に、プリ署名されたURLを生成するために使用される新しいS 3オブジェクトをインスタンス化します.
    const presignedGetUrl = await s3.getSignedUrl('getObject', {
        Bucket,
        Key: key,
        Expires: 60 * 5 // time to expire in seconds 5
      });
    
    オプションオブジェクトでは、キーが期限切れになるまで、バケツの名前、イメージキーと時間の長さを渡します.
    これでAWSに再配備できます.あなたがServerlessを更新しなかったならば、速い先端.ymlファイルは、コマンドに- fフラグを追加することができます.より迅速な展開のためのYML
    sls deploy -f signedUrl
    
    ブラウザ/postman(または同等)では、APIのゲートウェイURLにGETリクエストを行うことができます.例えば、cross origin resource sharing .応答URLをコピーすることができますし、ブラウザで貼り付け画像を参照してください.
    あなたがURLを確信していないならば、あなたはあなたのService
    Service Information
    service: demo-delete
    stage: dev
    region: eu-west-2
    stack: demo-delete-dev
    resources: 13
    api keys:
      None
    endpoints:
      GET - https://y32f66o0ol.execute-api.eu-west-2.amazonaws.com/dev/signed-url
    functions:
      signedUrl: demo-delete-dev-signedUrl
    layers:
      None
    
    イメージキーはイメージの1つです.確認するには、アマゾンのS 3であなたのバケットに行くことができます.
    https://y32f66o0ol.execute-api.eu-west-2.amazonaws.com/dev/signed-url?key=daniel-j-schwarz-REjuIrs2YaM-unsplash.jpg
    すべての画像を取得
    我々は実際には、ウェブサイトからそれらを呼び出すことが逆の方法で機能を行ってきた.プリサインされたURLでイメージを表示するには、我々のS 3バケットからリストを取得する必要があります.
    Serverlessに戻ってください.関数の下にある
    functions:
      images:
        handler: handler.images
        environment:
          BUCKET_NAME: ${opt:stage, self:provider.stage, 'dev'}-${self:custom.upload}
        events:
          - http:
              path: images
              method: get
              cors: true
    
    再び、バケット名は供給される変数によって決定されます.APIエンドポイントへのパスとリクエストを呼び出すためのメソッドがあります.
    ハンドラで.js add
    export const images = async (event) => {
    
      // if (event.headers['X-API-KEY'] !== process.env.API_KEY) {
      //   return {
      //     statusCode: 403
      //   };
      // }
    
      const data = await getAll();
    
      return {
        statusCode: 200,
        body: JSON.stringify(data),
      };
    };
    
    S 3 ListObjectSv 2メソッドはコールバック関数を必要とします.したがって、上では、私は約束を返すGetAllと呼ばれる別々の関数を呼びました.成功するならば、ハンドルは200のステータスコードを返して、データをstrinjifyします.
    生産アプリケーションでは、任意のエラーをキャッチし、必要なHTTPステータスコードとエラーを返す必要があります.
    前の関数
    const getAll = async () => {
      const s3 = new S3({});
      const params = {
        Bucket
      };
    
      return new Promise((resolve) => {
        s3.listObjectsV2(params, (err, data) => {
          if (err) {
            return resolve({ error: true, message: err });
          }
    
          return resolve({
            success: true,
            data: data.Contents,
          });
        });
      });
    };
    
    前に、S 3オブジェクトを起動し、いくつかのパラメータを設定します
      const s3 = new S3({});
      const params = {
        Bucket
      };
    
    前述のように、listObjectSv 2メソッドはコールバックを必要とします.私は、私が約束で包んだ匿名の機能を使いました
      return new Promise((resolve) => {
        s3.listObjectsV2(params, (err, data) => {
          if (err) {
            return resolve({ error: true, message: err });
          }
    
          return resolve({
            success: true,
            data: data.Contents,
          });
        });
      });
    
    データが返される場合、約束はデータオブジェクトからContentプロパティを継承して解決されます.
    関数SLS展開を展開し、APIゲートウェイURLを実行します.返される応答は以下のようになります.
    {
      "success": true,
      "data": [
        {
          "Key": "altanbagana-jargal-USCPvwqeO0U-unsplash.jpg",
          "LastModified": "2020-12-21T19:16:41.000Z",
          "ETag": "\"943f9736eb07dd0668006e0990af20df\"",
          "Size": 3377153,
          "StorageClass": "STANDARD"
        },
        {
          "Key": "daniel-j-schwarz-REjuIrs2YaM-unsplash.jpg",
          "LastModified": "2020-12-21T19:16:41.000Z",
          "ETag": "\"3988e5f9ba3c1118141dae396265054b\"",
          "Size": 2404910,
          "StorageClass": "STANDARD"
        }
      ]
    }
    
    我々は現在、場所を動的に画像を取得する当社のウェブサイトを更新する必要があります.
    次の部分では、次を更新します.我々のAWSサービスを呼び出して、キーで我々のAPIを確保するJSウェブサイト.
  • デモ:https://s3.console.aws.amazon.com/s3
  • リポジトリ242479152
  • パート1: