月光軒

ラーメンウォーカー 2019 を読んでいたら、川端商店街に新しい中華そばの店がオープンしていたことを知った。その名も『月光軒』。「ムンライケン」と読むみたいだ。早速行ってみたけど、この場所、金菜亭があった場所じゃないか。いつの間に変わったのか。

中華そばは醤油と塩、あと煮干そばもあった。どれにするか迷うな。つけそばも捨てがたい。今回は最初なので、看板メニューにしておこう。というわけで中華そばの醤油を注文した。

麺は多加水麺でツルツルかつプリっとしていた。初めての食感かも。豚と鶏のチャーシューはどちらも低温調理してあるのか、柔らかくてジューシー。そしてスープは鶏の旨味が溢れていて、ずっと飲んでいたいくらいだった。あと、うずらの玉子とトマトが入っているのは斬新で面白い。

期待以上のクオリティで、自分の中の醤油ラーメンランキングでトップ 5 に入った。はや川や KOMUGI、寿限無に勝るとも劣らない。はや川は味噌ラーメンにシフトしたしね…。会社の昼休みに行ける距離にあるので、醤油ラーメンが食べたくなったときの候補の筆頭になりそうだ。ひとまず、中華そばの塩と煮干そばとつけそばは食べなければ。

関連ランキング:ラーメン | 中洲川端駅呉服町駅祇園駅

Xamarin で秘密情報を管理するいくつかあるうちひとつの冴えたやりかた

この記事は、Xamarin Advent Calendar 2019 の三日目の記事です。

qiita.com

OAuth で使う ClientId と ClientSecret の管理で悩み中。 ハードコードしてはダメだし、Git リポジトリにコミットするのもダメ。

Xamarin.Android なら AndroidManifest.xml placeholders をサポートしているようなので、 この機能を使えば良いだろう。

github.com

ただ、Xamarin.iOS というか Xamarin. Forms ではどうしたものか。 2019 年も終わり間近だというのに、ベストプラクティスが見当たらない。

これが React + create-react-app での開発なら、 .env ファイルに REACT_APP_KEY=VALUE 形式で秘密情報を記述しておけば、 コードから process.env.REACT_APP_KEY で参照できるんだけどな。 同じようなことが Xamarin でもやりたい。 例えば、秘密情報を JSON ファイルに記述したら、 obj 下に自動的にコードが生成されたらいいんじゃないだろうか。

.NET Core 3.0 で gRPC が正式サポートされ、 Visual Studio で gRPC サービスプロジェクトの .proto ファイルを編集したら、 obj 下にコードが生成されるようになった。 それと同じような仕組みで実現できるかも、 と思って方法を調べていたら、 やろうとしていたことズバリそのものな NuGet パッケージを見つけてしまった。

github.com

NuGet で Mobile.BuildTools をインストールし、 プロジェクトのルートに secrets.json を作成。 この secrets.json に、例えば次のような秘密情報を記述したとする。

{
    "ClientId": "{Your ClientId HERE}",
    "ClientSecret": "{Your ClientSecret HERE}"
}

すると、{プロジェクトのルート}.Helpers 名前空間に次のような Secrets クラスが生成される。

// ------------------------------------------------------------------------------
//  <autogenerated>
//      This code was generated by Mobile.BuildTools. For more information or to
//      file an issue please see https://github.com/dansiegel/Mobile.BuildTools
//
//      Changes to this file may cause incorrect behavior and will be lost when 
//      the code is regenerated. 
//
//      NOTE: This file should be excluded from source control.
//  </autogenerated>
// ------------------------------------------------------------------------------

namespace SecretsSample.Helpers
{
    internal static class Secrets
    {
        internal const string ClientId = "{Your ClientId HERE}";

        internal const string ClientSecret = "{Your ClientSecret HERE}";
    }
}

あとは秘密情報が必要な箇所で、この Secrets クラスを使えばいい。 secrets.json と Secrets.cs は誤ってリポジトリにコミットしないよう、.gitignore に追加しておく。 なんだ、これでいいじゃん。

ちなみに、Mobile.BuildTools の Wikiデモアプリによると App Center にも対応しているみたいで、秘密情報を App Center の環境変数に設定しておいて、ビルド時に組み込むことができそうだ。ただ、App Center は使ってないので試していないけど。

コードファースト ASP.NET Core gRPC

この記事は、C# その2 Advent Calendar 2019 の二日目の記事です

qiita.com

はじめに

ASP.NET Core 3.0 で gRPC がサポートされた。 一方で WCF .NET Core に正式には移植されず、コミュニティによる開発にシフト。 業務では WCF をバリバリ使っているけど、gRPC への移行を検討しなければいけない時期になってきた。 2020 年には .NET 5 も来るし。

コードファーストで開発したい

Visual Studio で proto ファイルを編集したら保存時に C# のコードが生成されるようになったとはいえ、できれば proto ファイル書きたくない。

WCF では C# でデータコントラクトとサービスコントラクトのインタフェースを定義したら、 それをクライアントとサーバーの両方で利用できていた。 gRPC でも同じような体験が理想だ。

protobuf-net.Grpc

WCF から gRPC への移行方法を調べていたら、protobuf-net.Grpc というパッケージに出会った。

github.com

README には次のように書いてある。

protobuf-net.Grpc adds code-first support for services over gRPC using either the native Grpc.Core API, or the fully-managed Grpc.Net.Client / Grpc.AspNetCore.Server API.

WCF のときみたいに、コードファーストで gRPC サービスを開発できそうなシロモノに見える。

コードファースト ASP.NET Core gRPC をやってみる

.NET Core ライブラリ作成

クライアントとサーバーで共通のインタフェースを使うために、 クライアントとサーバーの両方で参照する .NET Core ライブラリプロジェクトを作成する。 名前は『HelloGrpc.Shared』。

NuGet パッケージ追加

プロジェクトには次のパッケージを追加しておく。

データコントラクトとサービスコントラクトを定義

この辺とても WCF っぽい。 引数が 1 つだけなのは protobuf-net.Grpc の制約。 gRPC でも 1 つなのは同じだし。 あと、DataMemberAttribute で Order を指定するのも必須。 .proto ファイルでもフィールドにタグ値を指定するけど、その代わりになる。

using System.Runtime.Serialization;
using System.ServiceModel;
using System.Threading.Tasks;

namespace HelloGrpc.Shared
{
    [ServiceContract]
    public interface IGreetingService
    {
        [OperationContract]
        Task<HelloReply> HelloAsync(HelloRequest request);
    }

    [DataContract]
    public class HelloRequest
    {
        [DataMember(Order = 1)]
        public string Name { get; set; }
    }

    [DataContract]
    public class HelloReply
    {
        [DataMember(Order = 1)]
        public string Message { get; set; }
    }
}
gRPC サービス作成

Visual Studio から gRPC サービスのテンプレートを選択してプロジェクトを作成。 名前は『HelloGrpc.Server』。

NuGet パッケージ追加

ASP.NET Core で gRPC サービスを実装するのに必要なパッケージはあらかた参照してあるけど、 下記のパッケージも参照に追加する。

gRPC サービス実装

services.AddCodeFirstGrpc() でコードファーストを有効にし、 endpoints.MapGrpcService<T>() で実際にコードで定義したサービスを登録するだけ。

using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ProtoBuf.Grpc.Server;

namespace HelloGrpc.Server
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCodeFirstGrpc();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<GreetingService>();
            });
        }
    }

    public class GreetingService : Shared.IGreetingService
    {
        public Task<Shared.HelloReply> HelloAsync(Shared.HelloRequest request)
        {
            return Task.FromResult(new Shared.HelloReply
            {
                Message = $"Hello {request.Name}"
            });
        }
    }
}
.NET Core コンソールアプリケーション作成

gRPC サービスを呼び出すクライアントは、.NET Core コンソールアプリケーションで作成する。 プロジェクト名は『HelloGrpc.Client』で。

NuGet パッケージ追加

HelloGrpc.Client プロジェクトに次のパッケージを追加。

  • Grpc.Net.Client
    • .NET 用 gRPC クライアント
  • protobut-net.Grpc
    • C# コードで定義した gRPC サービスのインタフェースをもとに動的にクライアントを生成してくれるパッケージ
gRPC クライアントを実装

protobut-net.Grpc が提供する GrpcClientFactory クラスが、インタフェースから動的に gRPC クライアントを生成する拡張メソッドを提供しているので、それを使う。

using System;
using System.Threading.Tasks;
using Grpc.Net.Client;
using HelloGrpc.Shared;
using ProtoBuf.Grpc.Client;

namespace HelloGrpc.Client
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var channel = GrpcChannel.ForAddress("https://localhost:5001");
            var client = channel.CreateGrpcService<IGreetingService>(); // インタフェースから動的に gRPC クライアントを生成
            var reply = await client.HelloAsync(new HelloRequest
            {
                Name = "Kubo"
            });
            Console.WriteLine(reply.Message);
            Console.ReadLine();
        }
    }
}
実行

コードファーストで作成した gRPC サービスをホストし、クライアントから呼び出すことに成功。

f:id:griefworker:20191016164249p:plain

まとめ

WCF から gRPC に移行する手段として、proto ファイルを書くのではなく、protobuf-net.Grpc を使いコードファーストで開発するのは良い線いってそうだ。さらに検証が必要だけど、希望が見えてきた。

なお、コードファーストで開発する別の選択肢としては MagicOnion もある。

github.com

既に大量の WCF 資産があり、MagicOnion だとそれらに結構な修正が必要そうだったので、 今回は選ばなかった。 ベンチマークを取ったわけではないけど、シリアライザに MessagePack を使っているので、 protobuf-net.Grpc を使った場合よりも速くなりそうな期待がある。 新規にコードファーストで開発するなら、MagicOnion という選択肢は有力だと思う。

五等分の花嫁(12)

五つ子がそれぞれ自分の道を歩み始めたなか、学園祭に突入。風太郎は学園祭で五つ子との関係に答えを出すと宣言したが、果たして誰を選ぶのか。それともまだ誰も選ばないのか。

一花は修学旅行でやらかしてしまったから、やはり分が悪そうに思える。それでも風太郎に対して「私だった?」「嬉しかった?」と尋ねたときの表情は小悪魔で、もう一花でいいんじゃね?って思わせるくらいの魅力があった。

ニ乃はツンデレだったころの面影はもはや無いけど、五つ子の中で一番家族思いなところは変わってない。そんな彼女が父親に対し振り絞った勇気が報われたのは、本当よかったなぁってホロリとなった。

五等分の花嫁(12) (講談社コミックス)

五等分の花嫁(12) (講談社コミックス)

海の中道海浜公園

秋も深まって絶好のレジャー日和だったので、海の中道海浜公園まで足を延ばしてきた。前回マリンワールドに行った際に、ついでに寄るつもりだったけど思いのほか暑くて断念したので、今回はいわばリベンジだ。公園とあるけど、国営公園で有料。

uminaka-park.jp

今回はマリンワールド側の駐車場から入れる、子供向けの遊具がある『子供の広場』を主戦場にした。ゲート入ってすぐにある『くじらぐも"ふわんポリン"』に次々と子供たちが吸い寄せられていく。遊べるのは小学生までで、大人は指をくわえて見ていることしかできない。残念。飛び跳ねてみたい。子供の付き添いという名目ではダメ?ダメかぁ。

ゲート入ってすぐにフードコートがあるので、弁当を持ってくるのを忘れても飢えずに済む。ただ、レトルト食品を食べてるみたいで、お世辞にも美味しいとは言えないな。その中でも佐世保バーガーの屋台は比較的マシだったけど。弁当は持参したほうが良いと思う。次からは外で買ってこよう。

ふわんぽりんは小さいヤツもあって、こっちは大人が付き添いで一緒に跳んでいた。あいにく娘はふわんぽりんの気分ではなかったので、またしても一緒に跳ぶことは叶わず。

『ローラーすべり台と海の生き物遊具』では、結構角度が急なウツボのトンネルに娘がチャレンジしていた。降りるとき多少の手助けは必要だったけど、なんとか出口に到達できるようになっていて、成長を実感。あとは、ローラー滑り台の上のほうにある『子供のとりで』が凄く気に入ったみたいで、主にかくれんぼをしながら長時間遊んでいた。この場所だけでどれくらいいただろうか。1時間どころじゃなかったと思う。

『スカイドルフィン』という大型の遊具にも連れて行きたかったけど、設置されている大芝生広場は子供の広場から結構距離があって、子供を連れて歩いて行くのは難しそうだった。とにかく広大で、園内の移動に有料のバスが運行しているくらい。自転車のレンタルができるので、娘が自転車に乗れるようになったら、家族でサイクリングすると気持ち良いかもな。幼稚園児だと遊園地に行っても乗れるものがあまり無いので、それよりは海の中道海浜公園のほうが楽しめそうだ。

ぼくたちは勉強ができない(14)

人の気持ちに聡くなれてきたのに、それに反して自分の嫌なところばかり見えるようになって苦しむ理珠を救うのが、成幸ではなく文乃というのは、二人の友情が特別だということなんだろうな。理珠と文乃が出会ってから現在の関係になる過程で、お互いが相手に憧れるようになったというのが、二人の重ねてきた時間を感じさせてウルっとなった。

今巻でついに理珠も自分の気持ちを自覚し、年も開けていよいよセンター試験。物語は最終章突入か?受験に恋愛、どんな結末を迎えるのかまったく想像がつかない。願わくば、受験は全員合格であってほしいところだ。

ボンバーキッチン天神店

薬院にあるボンバーキッチンの姉妹店『キッチンヨーロッパ』が春吉にオープンしたのを知って、そのうち行こうと思っていたら、『ボンバーキッチン天神店』に名前が変わっていた。キッチンヨーロッパだと思ったほど集客できなかったんだろうか…。行ってみたら、満席で賑わっているみたいだった。考えすぎか。ちょうど入れ替わりで席に付けたので、タイミング良かったな。

鉄板ハンバーグステーキを注文。選べるソースはデミグラスを選択した。ジュージュー音を立てて見るからに熱々のハンバーグが運ばれてきて、実に美味そう。デミグラスソースを選んだのは正解だったな。鉄板でソース自体焼かれるのが芳ばしくなってまた良いんだ、これが。

ハンバーグはオーソドックスで飽きの来ない、何度でも食べたくなるような品だった。肉汁がしっかり閉じ込められていてジューシー。箸を入れると溢れ出てくる様は洪水のよう。デミグラスソースとの相性は文句なし。付け合わせがポテトとパスタというのが、分かっているなあ。ソースを絡めて食べることで余すことなく完食した。

ナポリタンやミックスフライなど、他にも気になるメニューがたくさんある。天神に手頃な洋食屋、しかもそれがボンバーキッチンというのが、かなりポイント高い。薬院よりも行きやすいし。これはリピートするな。確実に。

関連ランキング:洋食 | 天神南駅西鉄福岡駅(天神)渡辺通駅