LoginSignup
1
1

More than 1 year has passed since last update.

AWS SAM CLIを用いてLambda+RubyでGemを使う方法

Last updated at Posted at 2022-12-16

概要

LambdaでRubyを使う際にNokogiriなどのGemを使おうとするとエラになってしまうので動かせるようにする

環境設定

※こちらはある程度されているものだと仮定します

ここらへんの記事を参考にcliツールなどを入れてください
https://qiita.com/itaya/items/a0f22addaab04456cae4

AWS側の準備

S3のバケットを用意
スクリーンショット 2022-12-17 5.21.25.png

初期設定

プロジェクト名=好きな名前を指定してください

sam init --runtime ruby2.7 --name プロジェクト名

下記のように選択肢を迫られるので、1→1→nを選択します

Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
	1 - Hello World Example
	2 - Multi-step workflow
Template: 1

Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.

Based on your selections, the only dependency manager available is bundler.
We will proceed copying the template using bundler.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: n

そうするとディレクトリが一つ出来上がります。

コーディング

ディレクトリの中のコードを変更していきます
hello_world/
このディレクトリの中がLambdaの本体コードになるのでこちらを変更します
app.rb

# require 'httparty'
require 'json'
require 'nokogiri'
require 'uri'
require 'kconv'
require 'net/http'

def lambda_handler(event:, context:)
  area = URI.encode_www_form_component('横浜')
  keyword = URI.encode_www_form_component('居酒屋')
  
  uri = URI.parse("https://r.gnavi.co.jp/area/jp/rs/?fwp=#{area}&date=&fw=#{keyword}")
  request = Net::HTTP::Get.new(uri)
  request["Authority"] = "r.gnavi.co.jp"
  request["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
  request["Accept-Language"] = "ja"
  request["Cache-Control"] = "max-age=0"
  request["Cookie"] = "_td_global=2c7201bb-65d9-447f-8871-5c8aef70e6f0; _ra=1664900409701|e581f62a-e16f-4c02-97dc-b7ab203924e6; GU=e9f8c8528b624ea8cb1a55aadf705bd0; gt=GT139faa476002ac1e4ae520fpfeoIzpEqTDWQ1Rwc2xzV; ds=622474de466075942cc80e90a606c14bc6c474c7b09327535e48d587017aa4c0; gUser=03139faa476003ac1e4ae520L_I2dpFCb1q8eMMN-5-LmU; gcom=%7B%22login_type%22%3A1%2C%22guser_type%22%3A0%7D; _gid=GA1.3.151665219.1669743686; __gads=ID=61224817bcdcc5e2:T=1669743685:S=ALNI_MYQItLoO9f62eC3t0aHssBPge-pXQ; __gpi=UID=00000b86e8eecc21:T=1669743685:RT=1669743685:S=ALNI_MZ324J7fmISVdaU-A1IuoqdhZBTIQ; _ts_yjad=1669743686386; _fbp=fb.2.1669743686439.1159228644; _gcl_au=1.1.1560200380.1669743686; __pp_uid=INDH6tuKhtkFKURk66AXkbVTWOoJTybu; __lt__cid=c5331b8a-2798-4df1-9a8c-afb6b1af0c3c; __lt__sid=ab800c27-56441560; _dctagfq=1318:1670338799.0.0|1319:1670338799.0.0|1320:1670338799.0.0|1321:1670338799.0.0|1536:1670338799.0.0|1841:1670338799.0.0|1856:1670338799.0.0|1871:1670338799.0.0|1886:1670338799.0.0|1901:1670338799.0.0|1916:1670338799.0.0|1931:1670338799.0.0; ___o2u_o2id=0793b44a-526d-4f6f-bbfb-c923eb5be40f; rtosrch=gg7t002%3Dhttps%253A%252F%252Fr.gnavi.co.jp%252Farea%252Fjp%252Frs%252F%253Ffwp%253D%2525E6%2525A8%2525AA%2525E6%2525B5%25259C%2526date%253D%2526fw%253D%2525E3%252581%25259F%2525E3%252581%252593%2525E7%252584%2525BC%2525E3%252581%25258D%26a567203%3Dhttps%253A%252F%252Fr.gnavi.co.jp%252Farea%252Fjp%252Frs%252F%253Ffw%253D%2525E5%2525B1%252585%2525E9%252585%252592%2525E5%2525B1%25258B%2526fwp%253D%2525E6%2525A8%2525AA%2525E6%2525B5%25259C; GHistory=a567203%3A110%3A1669744542%2Cgg7t002%3A110%3A1669744522; ghistory_reserve=a567203%3A1669744542%2Cgg7t002%3A1669744522; __cribnotes_prm=__t_1669744547013_%7B%22uuid%22%3A%227a38921c-4d2e-4d30-bcb9-80d0686da7f0%22%7D; cto_bundle=sGp-Ll9kUDVaaHJYMHN3SkFtYyUyQkFmUTh2QWdka0pTQ0xqWlhHVFpETzB3ckh4dG1ya0J4NTB1Y0Z1V09mOUtMRDJWRlBKbDNSU2FTMWFDRXgyOFU4Q0l6UzAzYWFoWE9TMVd0WmVqOFZVcjBmQ3JHVHJyNkFodzhVcDlKTGdRYTBIWXNEdHdET3RzeENSc0Q0eDRGdUlwJTJGS3pWJTJGaXk1QW9sajk1ZUhJRHNaelpaYSUyRllHR0klMkZlNnhWWXIlMkJYTXB3eU00eUw; s_sess=%20sc_oncook%3D%3B%20sc_prop1%3Dr%3B%20cpnt_referer%3D%3B; _dc_gtm_UA-43329175-1=1; _td=639fb236-c732-4fb7-b246-0a6ed66c2a87; _ga_L9BHK8C28C=GS1.1.1669743685.1.1.1669744820.51.0.0; _ga=GA1.1.111137152.1669743686"
  request["Sec-Ch-Ua"] = "\"Google Chrome\";v=\"105\", \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"105\""
  request["Sec-Ch-Ua-Mobile"] = "?0"
  request["Sec-Ch-Ua-Platform"] = "\"macOS\""
  request["Sec-Fetch-Dest"] = "document"
  request["Sec-Fetch-Mode"] = "navigate"
  request["Sec-Fetch-Site"] = "same-origin"
  request["Sec-Fetch-User"] = "?1"
  request["Upgrade-Insecure-Requests"] = "1"
  request["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
  
  req_options = {
    use_ssl: uri.scheme == "https",
  }
  
  response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
    http.request(request)
  end
  
  doc = Nokogiri::HTML.parse(response.body.toutf8, nil, 'utf-8')
  results = doc.css('.style_restaurantNameWrap__wvXSR').map do |target|
    target.text
  end
  {
    statusCode: 200,
    body: {
      message: "Hello World!",
      results: results
      # location: response.body
    }.to_json
  }
end

上記のコードが何をしているかは

これとか参考にしてください。
簡単に言うとぐるなびのサイトから情報を取得してパースしてます。

ローカルでコードの実行

下記のコマンドでビルドして

sam build --use-container

下記のコマンドで実行すると

sam local invoke HelloWorldFunction --event events/event.json

こんな感じでAPIのレスポンスが返ってきてることがわかります。

Invoking app.lambda_handler (ruby2.7)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-ruby2.7:rapid-1.66.0-x86_64.

Mounting /Users/itayayuuichirou/Documents/src/lambda/foo_scraper/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: dd6e7259-a4a0-4e33-bcac-8ca32c52071f Version: $LATEST
END RequestId: dd6e7259-a4a0-4e33-bcac-8ca32c52071f
REPORT RequestId: dd6e7259-a4a0-4e33-bcac-8ca32c52071f	Init Duration: 1.07 ms	Duration: 2778.83 ms	Billed Duration: 2779 ms	Memory Size: 128 MB	Max Memory Used: 128 MB
{"statusCode":200,"body":"{\"message\":\"Hello World!\",\"results\":[\"日吉 居酒屋 徳 0\",\"個室居酒屋 わら焼き直七(なおしち) 東戸塚店0\",\"居酒屋 まるは 0\",\"居酒屋さざん 中山駅前店0\",\"居酒屋さざん 日ノ出町駅前店0\",\"中華居酒屋 彩 関内0\",\"京個室 居酒屋 楓(かえで) 横浜駅前店0\",\"居酒屋 土間土間 横浜西口店0\",\"炭火居酒屋 もも 0\",\"居酒屋 土間土間 新横浜店0\",\"居酒屋 安ちゃん 0\",\"創作居酒屋 りき あざみ野店0\",\"〆蕎麦居酒屋 九 0\",\"中華居酒屋 ぼうず 0\",\"寿司居酒屋 七福 大口店0\",\"寿司居酒屋 太郎丸 上大岡店0\",\"寿司居酒屋 七福 戸塚店0\",\"和風居酒屋 末八 0\",\"寿司居酒屋 七福 上大岡店0\",\"九州居酒屋 エビス 市が尾店0\"]}"}%

デプロイ

では、このコードをデプロイしていきます。

sam package --output-template-file output.yaml --s3-bucket バケット名
sam deploy --template-file output.yaml --stack-name バケット名 --capabilities CAPABILITY_IAM

表示されるURLを叩くと
スクリーンショット 2022-12-17 5.56.02.png
こんな感じでJSONが返ってくるかと思います。

以上!!
(細かい動きとかなんでそうなるのかは理解できていないので、勉強します...)

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1