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


このポストでは、次を更新します.JSウェブサイト
  • は、AWSラムダ
  • を通して我々のS 3バケットからイメージ(オブジェクト)のリストのためにGET要求をします
    各々のイメージのための
  • は、予め署名されたURL
  • のGET要求をします
  • は次を更新します.事前に署名されたURL
  • を使用するJS画像コンポーネント

    サーバ側の支柱を得る
    ページ/インデックス.JSホーム関数の下に
    export async function getServerSideProps() {}
    
    次.データ取得の2つの主なタイプとして

  • GetStaticProps -ビルドデータでデータを取得し、基本的なHTMLファイル

  • getserversideprops -各リクエスト
  • のデータを取得する
    プリサインされたURLが5分後に期限切れになるので、GetServerSidePropsを使用して、各リクエストにデータを取得する必要があります.
    getserversidepropsの中にtry catchを追加し、エラーが次に発生します.JSは404を送って、見つけられないルートを示します.
    try {
    } catch (error) {
      return {
        notFound: true,
      };
    }
    
    試してみてください.キャッチは、フェッチ(オプションオブジェクトの繰り返しを保存する)で使用されるオプションのオブジェクトを追加する必要があります.APIを確保するためにapitleキーを使用します.ブログの最後に、AWSサービスに戻り、APIキーのチェックを追加します.
    クライアント側リクエストをするなら、我々はCorsを使用して、起源チェックを加えます
    try {
      const options = {
        headers: {
          'X-API-KEY': process.env.API_KEY,
        },
      };
    
      const imagesRes = await fetch('https://y32f66o0ol.execute-api.eu-west-2.amazonaws.com/dev/images', options);
      const { data: imagesData } = await imagesRes.json();
    } catch (error) {
      return {
        notFound: true,
      };
    }
    
    オプションの下に、我々のAPIキーで渡されたオプションで、我々の最初の取得要求です.私は応答を破壊して、後でどんな名前衝突も避けるためにデータ資産に名前を変えました.返される応答には、各イメージに必要なキーが含まれます.
    {
      "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"
        }
      ]
    }
    
    最後に待つと、フェッチリクエストからURLを保持する配列を設定する必要があります.foreachループを返されたデータに対して使用し、url plus keyを配列にプッシュします.
    const images = [];
    imagesData.forEach(({ Key }) =>
      images.push(`https://y32f66o0ol.execute-api.eu-west-2.amazonaws.com/dev/signed-url?key=${Key}`),
    );
    
    その後、URLをループし、それぞれの画像のフェッチの約束を持つ配列を設定します.約束を使おう.これらの要請を待つすべて.返される応答には、次のために必要なプリサインされたURLが含まれます.jsコンポーネント.
    const responses = await Promise.all(requests);
    
    さて、返されるレスポンスからJSONを取り出す必要があります.そのために、データを保存するために配列を設定します.約束の使用我々のデータ配列にJSONデータを押すことについて、我々はすべてを写像します.として、それは約束を使用してもいいかもしれない.要求のうちの1つが失敗した場合、all解決されます.明らかに、これは要求がどれくらい重要であるかに依存しています、そして、1つ以上が失敗するのがokならば.
    const data = [];
    await Promise.all(
      responses.map(async (r) => {
        const json = await r.json();
    
        data.push(json);
      }),
    );
    
    if (!data) {
      throw new Error('Data not found');
    }
    
    もしデータが我々のインデックスページに
    return {
      props: {
        data,
      }, // will be passed to the page component as props
    };
    
    最後のgetserversidePropsは次のようになります.
    export async function getServerSideProps() {
      try {
        const options = {
          headers: {
            'X-API-KEY': process.env.API_KEY,
          },
        };
    
        const imagesRes = await fetch('https://y32f66o0ol.execute-api.eu-west-2.amazonaws.com/dev/images', options);
        const { data: imagesData } = await imagesRes.json();
    
        const images = [];
        imagesData.forEach(({ Key }) =>
          images.push(`https://y32f66o0ol.execute-api.eu-west-2.amazonaws.com/dev/signed-url?key=${Key}`),
        );
    
        // map every url to the promise of the fetch
        const requests = images.map((url) => fetch(url, options));
    
        const responses = await Promise.all(requests);
    
        const data = [];
        await Promise.all(
          responses.map(async (r) => {
            const json = await r.json();
    
            data.push(json);
          }),
        );
    
        if (!data) {
          throw new Error('Data not found');
        }
    
        return {
          props: {
            data,
          }, // will be passed to the page component as props
        };
      } catch (error) {
        return {
          notFound: true,
        };
      }
    }
    
    ホーム関数では、小道具のデータが渡されていることを確認します.
    export default function Home({ data }) {
    
    メインタグ内で、イメージコンポーネントを置き換えます.
    <image src="/images/altanbagana-jargal-_eMbrsvO7jc-unsplash.jpg" width="{640}" height="{300}" />
    
    以下の各イメージのイメージコンポーネントを出力します.イメージコンポーネントは、マジックを行い、srcsetと関連するサイズと型を出力します.
    {
      data.map((imgUrl) => <Image key={imgUrl} src={imgUrl} width={640} height={300} />);
    }
    
    NPM実行devを実行していない場合は、http://localhost:3000/に行ってイメージを見てください.

    CSSグリッド
    必要に応じて、次のcssをスタイル/homeに追加できます.モジュールです.CSS(と未使用のCSSを削除する)は、画像を表示するには素敵なグリッドを追加します
    .grid {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-wrap: wrap;
      max-width: 800px;
      margin-top: 3rem;
    }
    
    @media (max-width: 600px) {
      .grid {
        width: 100%;
        flex-direction: column;
      }
    }
    

    APIのセキュリティー保護
    最後にするのは、サーバ/ハンドラの内部で、AWSサービスに戻ることです.以下のコードと再配備の行をコメントします.
    if (event.headers['X-API-KEY'] !== process.env.API_KEY) {
      return {
        statusCode: 403,
      };
    }
    
    今APIは、APIキーを使用してサーバーからのみアクセスできます.例えば、ブラウザから直接APIエンドポイントに行こうとするなら、403エラーを得ます.
  • デモ:https://dlw-nextjs-image-demo.vercel.app/
  • リポジトリ:https://github.com/dwhiteGUK/dlw-nextjs-image-demo
  • ここに要約するには
  • パート1:https://darrenwhite.dev/blog/nextjs-aws-image-demo-part-1
  • パート2:https://darrenwhite.dev/blog/nextjs-aws-image-demo-part-2
  • パート3(最終):https://darrenwhite.dev/blog/nextjs-aws-image-demo-part-3