.NET で Firestore

Firebase を使ってアプリをサクッと作れるようになりたかったので勉強することにした。まずは Firestore。アプリは Xamarin で作るつもりなので、C# から Firestore を触ってみる。NuGet で専用のパッケージが公開されているので、それを使う。まだベータ版だけど、Firestore 自体まだベータ版だし。

www.nuget.org

Firestore で CRUD をやるサンプルを書いてみた。コードはサクッと書けたけど、GCP 外から Firestore にアクセスするために必要な、アクセスキーファイルを入手するのが最初にして最大の関門だった。GCP の 「API とサービス」の「認証情報」でサービスアカウントを作成して、アクセスキーファイルをダウンロードしておかないといけない。

using Google.Cloud.Firestore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace FirestoreSample
{
    class Program
    {
        const string ProjectId = "your-project-id";

        static void Main(string[] args)
        {
            // API とサービスの認証情報でサービスアカウントを作成し、
            // ダウンロードしたアクセスキーファイルのパスを環境変数で指定
            Environment.SetEnvironmentVariable(
                "GOOGLE_APPLICATION_CREDENTIALS",
                Path.Combine(AppContext.BaseDirectory, "your-key.json"));

            MainAsync().GetAwaiter().GetResult();

            Console.WriteLine("Press Enter Key.");
            Console.ReadLine();
        }

        static async Task MainAsync()
        {
            var db = FirestoreDb.Create(ProjectId);

            // books コレクションにドキュメント追加
            var book1Ref = await db.Collection("books")
                .AddAsync(new Dictionary<string, object>()
                {
                    ["title"] = "かぐや様は告らせたい",
                    ["price"] = 500,
                });

            // books コレクションに ID 指定でドキュメント追加
            var book2Ref = db.Collection("books").Document("bokuben");
            await book2Ref.CreateAsync(new Dictionary<string, object>()
            {
                ["title"] = "ぼくたちは勉強ができない",
                ["price"] = 450,
            });

            // books を価格順にソートして取得
            var querySnapshot = await db.Collection("books")
                .OrderBy("price")
                .GetSnapshotAsync();
            foreach (var doc in querySnapshot.Documents)
            {
                Console.WriteLine($"{doc.GetValue<string>("title")}({doc.GetValue<int>("price")}円)");
            }

            // ドキュメントを更新
            await db.Collection("books")
                .Document("bokuben")
                .SetAsync(new Dictionary<string, object>()
                {
                    ["price"] = 420,
                }, SetOptions.MergeAll);

            // ID を指定して 1 件取得
            var documentSnapshot = await db.Collection("books")
                .Document("bokuben")
                .GetSnapshotAsync();
            Console.WriteLine($"{documentSnapshot.GetValue<string>("title")}({documentSnapshot.GetValue<int>("price")}円)");

            // ドキュメントを削除
            await db.Collection("books")
                .Document(book1Ref.Id)
                .DeleteAsync();
            await db.Collection("books")
                .Document("bokuben")
                .DeleteAsync();
        }
    }
}

実行してみた結果は下の通り。

f:id:griefworker:20180904163909p:plain

Xamarin だとロジックの大部分を iOSAndroid で共有できるので、Firestore を単純にデータベースとして使い、ロジックを .NET Stadard ライブラリとして書いて、iOSAndroid から使う戦略が使えそう。

『WEB+DB PRESS Vol.106』を読んだ

WEB+DB PRESS Vol.106』を読み終わったので、毎度の感想メモ。

特集1: [コードで超わかる!]実践Android/iOSアプリ設計

.NET の WPF で生まれた MVVM が、今では Android /iOS の開発で有力なアーキテクチャになるとは感慨深いものがある。Android はデータバインディングを公式にサポートしているのに対し、iOS は RxSwift を使って頑張らないといけないのがツライが。

MVVM に Flux を組み合わせるのはやり過ぎなのではと思うんだけど、採用事例が多いんだろうか。自分が MVVM をやるなら、モデルはドメイン駆動開発風味のレイヤーアーキテクチャでやるだろうな。もしくは、View と ViewController に ReSwift(Redux)。

特集2: [速習]Spring Boot

Java は 10 から型推論が入ったし、ラムダ式も 8 から使えるし、IntelliJ IDEA という強力な IDE もあって、その書き心地はだいぶ Lightweight になったと言っていいと思う。 SpringBoot は Rails の scaffolding ほどの衝撃では無いにせよ、Java での Web 開発でツラかった部分が改善されて、LL のメジャーな Web Application Framework と遜色ない生産性に思えた。

もともと Java のエコシステムの充実っぷりは頭一つ抜きでているし、自分なら Scala で Play Framework よりは Java + SpringBoot を選ぶな。エコシステムどうにかしないと .NET は勝ち目ないよねぇ。

特集3: 仮想DOM革命

仮装 DOM の差分更新によって、ビューを「状態を受け取り HTML/JSX を返す関数」と見なせるようになったのは革命だと思う。 そこからさらに進んで Flux のような単方向データフローのアーキテクチャが生まれたし、フロントエンドの世界に与えた影響は jQuery と同じかそれ以上かもしれない。

その証拠に、仮装 DOM はブラウザを飛び出し、React Native や Flutter でアプリの世界へ。仮装 DOM を今から初めて遅すぎることはなく、React の他に Vue も仮想 DOM を採用していることからも、jQuery 同様長く生きるのは間違いなさそう。

WEB+DB PRESS Vol.106

WEB+DB PRESS Vol.106

Swashbuckle.AspNetCore で Failed to load API definition に遭遇したら

開発中の Web API に後から Swashbuckle.AspNetCore を追加したはいいけど、いざ Swagger UI を表示してみたら「Failed to load API definition」というエラーになって API 一覧が見れない。こんな感じのやつ。

f:id:griefworker:20180903160836p:plain

このエラーに遭遇したら、ググる前にまず swagger.json がちゃんと生成されているか確認すること。

今回の場合、/swagger/v1/swagger.json にアクセスしてみたら、スキーマ ID が重複しているのが原因だとわかった。 スキーマ ID はデフォルトだとクラス名が使われるので、名前空間を含めたクラス名をスキーマ ID に使うように、Startup 内で指定したら解決。

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Info
    {
        Title = "My API",
        Version = "v1"
    });

    // スキーマ ID は名前空間含めたクラス名にする
    c.CustomSchemaIds(type => type.FullName);
});

何度もハマったので、忘れないようにメモを残して置く。

八坪亭

イタリアンでもフレンチでもなく、洋食が食べたい気分たったので、以前ソワニエに掲載されていた、中央区清川にある『八坪亭』に行ってみた。

お腹と相談した結果、ボリュームがありそうなエビフライとスコッチエッグのセットを注文。注文を受けてから作り始めるそうなので時間がかかるみたいだ。最初に出されたスープを飲みながら気長に待つことに。

気長に待っていると、お待ちかねのスコッチエッグとエビフライが運ばれてきた。期待通りのボリューム。この圧倒的洋食感よ。

スコッチエッグとエビフライはどちらもサクッと揚がっていて、丁寧な仕上がり。頬張ると口の中が幸福感で満たされた。

今回は夕飯で訪れたのでノータイムで入れたけど、ランチだとそうはいかないだろうな。回転率はお世辞にも良くはなさそうなので、時間と心に余裕があるときに行くのがオススメ。職場の近くにこういった洋食の店が欲しいもんだ。

獅子王

福岡市大名に『獅子王』という味噌ラーメン店があるということをテレビで知ったので行ってみた。本場札幌で行列のできる人気店なんだとか。2018年度の福岡ラーメン本には載っていなかったのでノーマークだった。

食べたのは『濃厚辛味噌らーめん』。すりおろしたジャガイモが溶け込んだスープはポタージュ、いや、ビシソワーズのようにまろやか。 麺はぷりっとした弾力で食べ応えあり。 自分のデータベースにはない新しいスタイルの味噌ラーメンで、新鮮かつ美味かった。

札幌らーめん 獅子王 福岡大名店

食べログ 札幌らーめん 獅子王 福岡大名店

キャロット

天神コア7Fにある『キャロット』でランチを食べることにした。この店は天神で老舗の洋食屋だけど、まだ行ったことがなかったので。自分が行った時間がちょうどズレていて、入れ替わるように入店できたので運が良かった。

ミラノ風ハンバーグのAランチを注文。 ハンバーグとライスに食後のコーヒーが付いて税込920円と、内容的には割高だけど、まぁ場所代と割り切ろう。

ミラノ風ハンバーグはレトロな味わい。クリーミーなソースにチーズがプラスされ、より一層クリーミーに感じた。

食後はコーヒーで一息。ランチで食後にコーヒーなんて飲んだの久しぶりかも。たまにはのんびりしたランチも良いもんだ。

そういえば天神コアも再開発で取り壊される予定だったと記憶しているけど、この店はどうなるんだろう。友楽みたいに移転するんだろうか。再開発やるのは結構だけど、歴史のある名店が天神から無くなってしまうのは惜しい。

みすゞ庵

天神で働いて10年以上経つけど、ベスト電器のビルの1階に入ってる『みすゞ庵』に行ったことがなかったので行ってみた。地上だけでなく地下まであって、席数が多かったのは意外。それでもほぼ満席だったけど。

今回のお目当は『カツカレーそば』。カレーそばにトンカツがのった変わり種。見た目かなりのインパクトがあるな。

見た目のインパクトに反して、味は調和が取れていた。つゆはカツカレーに合うよう試行錯誤したものらしい。トンカツは薄い衣でサクっと揚がっているし、蕎麦も平麺だし、つゆはどちらかというとスープに近いし、まるでパーコー麺みたいだ。そう考えると全然アリに思えるな。