Lambdaの関数URLとNetworkXを利用してネットワークグラフをWeb画面に表示する


AWS Lamdbaに関数URL(AWS Lambda Function URLs)という機能が搭載され、爆速でAPIを構築できそうかつ、フロントとバックの画像のやりとりを実現してみたかったので、いじってみました。  
NetworkX( https://networkx.org/ )はあくまで、グラフを描画するためだけなので、深くいじりません。  

Web画面はreactを利用し、lambdaのコードはPythonで書いていきます。  

## 関数URLの準備
本当に早くてびっくりしました。  
1. 関数の作成から、関数名を入力します  
   ![スクリーンショット 2022-07-27 19.22.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412976/189ede0c-7e5c-fb9a-9b0b-cb172491a27f.png)

2. 下の方にスクロールをして、「詳細設定」を開き、以下を選択します
   - 関数URL
   - 認証タイプ -> NONE
   - オリジン間リソース共有(CORS)を設定
   ![スクリーンショット 2022-07-27 19.22.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412976/aa35dd5b-1b07-4498-e688-ee01c2ee43da.png)  
3. これで最低限が完了です。

4. 右下に関数URLが作成されているため、開く
![スクリーンショット 2022-07-27 19.22.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412976/1a08b0dc-8326-85ad-f930-e8fc225ed6d0.png)

5. アクセスして確認してみる
![スクリーンショット 2022-07-27 19.24.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412976/b21e063f-8b12-6b9f-21fc-afa321c0b7b5.png)

   初期のソースは以下ですね。  
   ![スクリーンショット 2022-07-27 19.24.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412976/00e80a20-1c9a-77d7-7749-8d8eddee5e9f.png)

6. NetworkXとグラフプロットのコードを追加します
   1. NetworkXをしてグラフを準備
   1. Lambdaのtmpフォルダ(容量の拡張ができるようになりましたね！)にファイルを吐き出し
   1. ファイルの情報を保持して、実ファイルの削除
   1. base64でデコードしてreturnする
   という流れです。(いらんもんimportしてるかも)  
   https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/lambda-proxy-binary-media.html を参考に画像ファイルのやりとりを実現してます
   ```python
   #!/usr/bin/env python
   # -*- coding: utf-8 -*-
   
   import json
   import base64
   import boto3
   import os
   import networkx as nx
   import matplotlib.pyplot as plt
   import sys

   def lambda_handler(event, context):
   
     G = nx.fast_gnp_random_graph(10, 1) # 適当にグラフ作成
     nx.draw_circular(G) # 適当にグラフ作成
     save_folder = os.path.join("/tmp") # 作業フォルダ
     file_name = save_folder + "/NetworkXImg.png"
     plt.savefig(file_name) # ファイルの保存
     plt.close() # ファイルを閉じる
   
     image = open(file_name, "rb").read() # 画像の読み込み
     os.remove(file_name) # tmpデータを削除
     return {
            'headers': { "Content-Type": "image/png" },
            'statusCode': 200,
            'body': base64.b64encode(image).decode('utf-8'),
            'isBase64Encoded': True
     }
   ```
7. NetworkXのライブラリ情報は、以下の記事を参考にzip化してソースコードと一緒にアップロードしちゃいます
   https://qiita.com/ta983kata/items/4c88e57336c11b683ec2#lambda-layer%E3%81%AE%E8%BF%BD%E5%8A%A0

8. 以下の記事を参考に、`numpy`と`matplotlib`のARNを持ってきてLayer部分にARNを指定します
   https://qiita.com/polarbear08/items/202752d5ffcb65595bd9
   ![スクリーンショット 2022-07-27 19.51.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412976/7e3aa875-53bb-ecbe-10df-1d610e12bd01.png)
9. Lambdaの準備が完了したので、5で確認したURLをもう一度確認してみます
   ![スクリーンショット 2022-07-27 19.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412976/8cad61ed-21ce-cb57-c467-dac491a70033.png)


お〜〜！簡単！



## フロントの準備
1. 以下のコマンドを実行し、プロジェクトを作成します  
   ```shell
   $ npx create-react-app test-project
   ```
2. 必要最低限で、`test-project/src/App.js`を少しいじります
   ```javascript
   import React, { useState, useEffect } from "react";
   import './App.css';
   
   function App() {
   
     return (
       <div className="App">
         <header className="App-header">
           <>関数URLの結果↓</>
           {/* src部分に関数URLの情報を入力 */}
           <img src={`https://XXXXXXXXXXXXXXXXX.lambda-url.ap-northeast-1.on.aws/`} />
         </header>
       </div>
     );
   }
   export default App;
   ```
3. reactのデフォルトは暗い色合いなので少しだけCSSをいじります。(カレントディレクトリのApp.css)
   - 背景色と文字色だけ変えます
   ```css
   .App-header {
     background-color: #fff;
     min-height: 100vh;
     display: flex;
     flex-direction: column;
     align-items: center;
     justify-content: center;
     font-size: calc(10px + 2vmin);
     color: black;
   }
   ```

4. 画面確認してみます
   ![スクリーンショット 2022-07-27 20.12.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412976/9e297923-f4df-2e29-3296-4b6297d18a31.png)




爆速でした。


## 最後に
Lambdaの関数URLは、技術検証で大いに活用できそうです。  
また、追加料金を払うことでLambdaのtmpフォルダの容量も拡張できるそうなので、開発の幅が広がりそうです。