AWS API GatewayでフックされるLambdaをC#で書いてみる

最近仕事でAWSに触っています。
また、12/1にAWSのLambdaがC#に対応したこともあり、Lambdaで色々遊んでます。

AWS Lambda Supports C#

今回の投稿では、HTTPリクエストを受けたAPI GatewayがLambdaをフックしてレスポンスを返す、ということをやってみます。

準備

AWS Toolkitを使い、.NET Coreアプリケーションとして開発します。 いくつかの投稿で詳しく説明されています。

qiita.com

blog.shibayan.jp

Lambda

AWS Lambda Projectを作成し、Lambda Functionを実装します。
ここではParamクラスをリクエストとして受け取り、そのままレスポンスとして返すだけの簡単なLambdaを定義します。

  • JSONでリクエスト・レスポンスするので、シリアライゼーションにAmazon.Lambda.Serialization.Json.JsonSerializerを使います。
  • 何も実装・継承していない素のクラスで、Lambdaで呼び出すハンドラ(この場合LambdaTestHandler)をPublish時に指定します。
using Amazon.Lambda.Core;

namespace LambdaTest
{
    public class LambdaTestFunction
    {
        [LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
        public Param LambdaTestHandler(Param input, ILambdaContext context)
        {
            return input;
        }

        public class Param
        {
            public string PathValue { get; set; }
            public string QueryValue { get; set; }
            public string HeaderValue { get; set; }
        }
    }
}

API Gateway

次にコンソール画面から、"test-api"というAPIを作成していきます。
test-apiでは、GETメソッドを定義し、パスパラメータ・クエリパラメータ・リクエストヘッダの値をJSON形式にしてLambda(先程作成したLambdaTestFunction)へ渡します。 f:id:ohke:20161229092432j:plain

  • パスパラメータはブラケットでくくられたリソース(ここでは、/{pathparam})として定義します。
    f:id:ohke:20161229092606j:plain

  • メソッドリクエストではLmabdaの入力値として使用したいパラメータを定義します。

    • pathparam、queryparam、headerparamとします。 f:id:ohke:20161229092625j:plain:w350
  • 統合リクエストではJSON形式でLambdaへ渡るようにマッピングを定義します。

    • Content-Typeはapplication/jsonとします。
    • テンプレートでは、$input.params('メソッドリクエストで定義した名前')でパラメータへアクセスできます。
{
    "PathValue": "$input.params('pathparam')",
    "QueryValue": "$input.params('queryparam')",
    "HeaderValue": "$input.params('headerparam')"
}
  • レスポンスは何も設定しません。
    • Lambda側でJSONリアライザを指定しているので、レスポンスクラス(ここではParam)がJSON形式で返されます。

最後にテストをすると、JSONの値が返ってくるようになります。 f:id:ohke:20161229092738j:plain:w400

まとめ

簡単なJSONエコー?ではありますが、EC2などのサーバを一切使わずに、Web APIを提供できるようになりました。

ASP.NET Core MVCでCache-Controlを設定する

ASP.NET Advent Calendar 2016 - Qiitaの21日目の投稿となります。 テーマをガラッと変えました。

ASP.NET Core MVCのコントローラから返されるHTTPレスポンスヘッダのCache-Controlを設定してみます。

Cache-Control

Cache-Controlは、ブラウザ(やキャッシュサーバ)へキャッシュの利用有無や有効期限などの情報を提供する、HTTPヘッダです。 ブラウザの開発者モードで確認できます。

f:id:ohke:20161220212434p:plain:w250

詳しくはRFC7234を見てください。

ResponseCacheAttribute

ASP.NET CoreのCache-Controlでは、従前のOutputCacheAttibuteクラス(System.Web.Mvc)が使えず、代わりにResponseCacheAttibuteクラス(Microsoft.AspNetCore.Mvc)が提供されています。

キャッシュの有効化と無効化

まずはブラウザに30秒間キャッシュさせる方法を見てみましょう。

  • Durationパラメータにキャッシュする秒数を指定します。
[ResponseCache(Duration = 30)]
public IActionResult Index()
{
    return View();
}
  • max-ageにてキャッシュの有効期限が指定されます。
    • publicの詳細は後述。

f:id:ohke:20161220224449p:plain

次に、常に更新を確認し、更新が無い場合にはキャッシュを使う設定です。

  • Durationパラメータを0とする。
  • LocationパラメータをResponseCacheLocation.Noneとする。
[ResponseCache(Location = ResponseCacheLocation.None, Duration = 0)]
public IActionResult Index()
{
    return View();
}
  • max-age=0で、常に有効期限切れのキャッシュとなる。
  • no-cacheの有無による違いは無いはずですが、ブラウザの実装に依存します。 f:id:ohke:20161220224501p:plain

なお、更新の検知ではレスポンスヘッダのLast-Modified(最新更新日時)やETag(ファイルハッシュ値)が使われます。 次回以降のリクエストヘッダにIf-Modified-SinceLast-ModifiedIf-None-MatchETagの値が設定され、サーバ側で比較して更新があった(サーバ側の最新の値と一致しない)場合のみ新しいレスポンスを返します。

最後に、一切キャッシュさせない設定です。

  • NoStoreパラメータをtrueとする
[ResponseCache(NoStore = true)]
public IActionResult Index()
{
    return View();
}
  • no-storeでブラウザは常にサーバから再取得する(=一切キャッシュを使わない) f:id:ohke:20161220224513p:plain

Location

キャッシュ場所をLocationパラメータで設定します。

  • ResponseCacheLocation.None: no-store
  • ResponseCacheLocation.Client: private
    • クライアント(=ブラウザ)のみにキャッシュされる。
  • ResponseCacheLocation.Any: public
    • クライアントとキャッシュサーバ(=プロキシサーバなど)の両方でキャッシュされる。
[ResponseCache(Location = ResponseCacheLocation.Client, Duration = 120)]
public IActionResult Index()
{
    return View();
}
Cache-Control: private, max-age=120
Pragma: no-cache

CacheProfileName

コントローラのメソッドやクラスを跨いで使う設定については、名前を付けて参照することができます。

  • Startup#ConfigureServices内で下記のように設定します。
    • ここでは120秒でキャッシュする"Default"という名前の設定を追加。
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(options =>
        {
            options.CacheProfiles.Add("Default",
                new Microsoft.AspNetCore.Mvc.CacheProfile()
                {
                    Duration = 120
                });
        });
    }
}
  • コントローラクラスやメソッドにてCacheProfileNameパラメータで名前を指定する。
[ResponseCache(CacheProfileName = "Default")]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

まとめ

ASP.NET CoreにてCache-Controlを制御する方法について調べてまとめてみました。

とはいえ、ブラウザの実装依存の部分も多々ありますので、ヘッダが正しく設定されていること、そして意図通りにキャッシュにアクセスされていることを開発者モードなどで確認することをおすすめします。

有給消化期間の過ごし方

転職 Advent Calendar 2016 - Qiitaの14日目となります。 少しポエムも含みます。

今年11月にSIerからWebサービスの会社へ転職しました。

早くから退職することを報告していたこともあって、幸いにも有給消化として1ヶ月のお休みをいただくことができました(これでも10日ほど余らせてしまいました)。 その際に、職場の先輩が「有給中は何するの?もし自分が退職することになっても、何したらいいかわからない」とぼやいておりました。

今まで長期休みを取らずに働いていた人は、意外と同じような疑問を持つ人が多いのかなと思いましたので、参考までに自分が有給中に何をしていたのかを書いてみたいと思います。 (そもそも有給消化期間などくれない!というもっと切迫した問題を抱える人もいる中、贅沢な悩みです。)

次の仕事に向けた勉強をする

私の場合、1プロジェクト10~数十人+の大規模開発が主流のSIerから、組織全体でエンジニア数十人程度の少数精鋭のWebサービス企業への転職でした。 また、技術スタックもインフラからアプリーケーションへ、言語環境もJavaから.NETへと変わるため、まずは足を引っ張らないようにならなければという思いのもと、次の職場で必要となりそうな技術を中心に勉強しておりました。

何を勉強すべきか

転職時の調査や面接等で必要なスキルはあたりがついているかと思います。 もし不安なら内定後の面談で何を勉強しておいたほうが良いか直接確認しても良いと思います(私はそうしました)。

私の場合、具体的にはGit、C#ASP.NET MVCの3点について勉強しました。

  • Git(に限らずその他のバージョン管理システムでも同様ですが)については、使い方を誤れば他の開発者へ迷惑をかけることにもなるため、慣れておいたほうが良いです。
    • 私の場合はVisual Studio Team Servicesで個人のレポジトリを作成して練習していました。
    • ただし一人だと、コンフリクトの解消など、チーム開発での実践的な使い方は意識的に習得する必要があります。

モチベーションの維持

今まで働き詰めで「あれ面白そう、いつか勉強したい」と23時の職場で思っていたとしても、いざ1ヶ月の長期休みをもらうと、最初の1週間くらいしか頑張らず、あとはなんかテキトウに。。。ダラダラと。。。というのがよくあるパターンかと思います。

せっかくのお休みを有効活用したかったので、場所とツールを変えることでモチベーションの維持を図りました。

場所を変える

日中、家で一人勉強していて、特に疲れてくると寂しくなって気分が落ち込みますSoft Skillsの人もこんなこと言ってました。全く同じ体験をしました。

しばらくすると、その平和と静寂が少し不安なものに感じられるようになった。 気がつくと、窓の外を見て何か生命の兆しを探しているようになったのである。

なので、日中は人がいるところで作業するようにしました。 私の場合、近くの市立図書館、市内の大学図書館スターバックスをよく使っていました。

  • 多くの大学がその地域の市民に向けて図書館を開放しています。
    • さらに学食を開放していることもありますので、お昼ごはんも調達できるかもしれません。

ツールを変える

まとまった知識の学習ではやっぱり本を使うことが多いのですが、朝から読んでいると、昼過ぎくらいにだんだん字を追うだけになっていき、頭に入りにくくなっていることに気づきました。

そこで、気分転換も兼ねて動画学習サイトを利用し始めましたが、これが当たりで、午後の半分くらいは動画で勉強していました。 動画を見ながら手を動かして学ぶというスタイルのコンテンツが多く、頭が疲れていても内容を咀嚼できるというのが良かったです。

私は主に2つを使い分けていました(Pluralsightは年間契約して今でも利用しています)。

  • Udemy
    • 日本語コンテンツが充実
      • 日本語ですと1.5倍速で再生してもなんとかついていけるので、お得
  • Pluralsight
    • ほぼ全て英語ですが、CCが提供されている場合もあり、何よりも.NET系のコンテンツが充実
      • CCは表示・非表示を切り替えられる字幕で、原文英語でもリアルタイムでGoogle翻訳できる

送別会で壮行される

転職する人であれば、多かれ少なかれ前の仕事や人間関係や職場環境にネガティブな感情を持っているかと思います。 たとえそうであったとしても、よっぽどのことでなければ送別会は招かれたほうが良いです。

  • 自分が頑張ったことを褒め称えてもらいましょう
    • 無駄なキャリアではなかった、ちゃんと意味があったということを最後に思い知るかもしれません
  • 上司や同僚から最後のフィードバックをもらいましょう
    • もしかしたら次の目標が生まれるかもしれません

実家の問題と向き合う

私もそうですが、進学や就職を機に関東へ来て、正月や盆にしか実家に帰らず早数年、という人も多いのではないでしょうか。 そうやって過ごす間に、実家ではいろいろな問題が進行していて、でも時間的にも距離的にも手が出せていないことがあるかもしれません。

  • 例えば、父(母)が退職以来、外に出ずテレビばっかり見るようになった
  • 例えば、家屋にガタが来ており、手入れが必要になった

私の実家の場合は、妹が二十歳を超えて家事・通学・就業をしていない、いわゆるニート状態が数年続いておりましたので、休みの間にこの問題を前進させたいと思っておりました。

実家に帰り、適性や就きたい仕事などについて妹とよく話をし、履歴書を一緒に作成して、求人サイトに登録して何社か応募し、自分が実家から離れた後も1週間単位で継続して連絡・相談するように伝えました。

ただ、この手の問題は解決する意思を持った人がいなくなると途端に元の木阿弥になってしまいやすいらしく、連絡は2週目には来なくなりました。相変わらず何も始められていないようです。

私も転職後にドタバタしてフォローしきれていなかったことが失敗でした。 これは1ヶ月程度で解決しない問題なのかもしれません。意外と短いのです。

家族と旅行する

自分は休みでも家族(奥さん)は休みではないので、意外と家族で旅行するチャンスは少ないです。 それでも少し休みを取ってもらい、2泊3日で石垣島へ旅行しました。

転職に際しては色々迷惑をかけてしまったので、一緒にリフレッシュしました。

f:id:ohke:20161210135333j:plain

まとめ

私の有給消化期間の過ごし方を紹介しましたが、「ずっとゲームをしてました」でももちろん良いと思っています。

仕事と仕事の変わり目で、一旦仕事から離れることが一番大事だと思っています。 だからこそ、有給消化期間はなんとしてでももぎ取るようにしましょう。