はじめに
以前,『Domain Modeling Made Functional』という本を勧められて F# に興味は持ったものの,その時は読むのを挫折してしまいました・・・しかし,あらためて関数型ドメインモデリングに興味が湧いてきた今日この頃。何はともあれ,まずは Hello World!
(追記)
年末年始でやっと本も読めたので,そのうち何か書きたいと思います。
Docker コンテナ
dotnet core 用の Docker イメージを使用します。
$ docker run --rm -it -w /home/dotnet -v $PWD:/home/dotnet mcr.microsoft.com/dotnet/core/sdk:3.1-bionic bash
なんか以前と場所が変わってますね。いまはココらしいです。
参考:公式の .NET Docker イメージ
コンテナ内では dotnet
コマンドが使えるようになります。
作業ディレクトリをマウントしておくことで,後ほど VS Code などで開いて編集できるようになります。
WSL の場合
WSL の場合は docker が認識するパスとズレがあるので,先に以下のようなコマンドで $PWD
を揃えておく必要があります。
export PWD=`pwd | sed -r 's/\/mnt(.*)/\1/'`
Console Application
まずは,コンソールアプリのテンプレートを使用してプロジェクトを作成してみます。
(コンテナ側)
$ dotnet new console -lang "F#" -o HelloWorld
プロジェクトを指定して実行します。
(コンテナ側)
$ dotnet run --project HelloWorld
Hello World from F#!
無事に Hello World from F#!
が表示されました。
カレントディレクトリに移動すれば --project
は省略できます。
Web API
折角なので Web API も試してみましょう。
ホスト側からアクセスするにはポートをバインドします。
テンプレートで使用されるデフォルトは 5000 と 5001 です。
(ホスト側)
$ docker run --rm -it -p 5000:5000 -p 5001:5001 -w /home/dotnet -v $PWD:/home/dotnet mcr.microsoft.com/dotnet/core/sdk:3.1-bionic bash
Web API のテンプレートでプロジェクトを作成します。
(コンテナ側)
$ dotnet new webapi -lang "F#" -o WeatherForecast
プロジェクトを指定して実行します。
(コンテナ側)
$ dotnet run --project WeatherForecast
サーバーが起動しました。(Ctrl+C で停止します)
別のターミナルからコンテナに入って確認してみます。
(ホスト側)
$ docker exec -it <<container_name>> bash
curl 叩いてみます。
(コンテナ側)
$ curl -kL http://localhost:5000/WeatherForecast
5000 (http) にアクセスすると 5001 (https) にリダイレクトされます。
-
-k
SSL のエラーを無視します -
-L
自動的にリダイレクト先の URL も叩いてくれます
[{"date":"2020-01-12T01:16:46.0608601+00:00","temperatureC":51,"summary":"Mild","temperatureF":123},{"date":"2020-01-13T01:16:46.0608821+00:00","temperatureC":32,"summary":"Cool","temperatureF":89},{"date":"2020-01-14T01:16:46.0608834+00:00","temperatureC":28,"summary":"Mild","temperatureF":82},{"date":"2020-01-15T01:16:46.0608842+00:00","temperatureC":22,"summary":"Hot","temperatureF":71},{"date":"2020-01-16T01:16:46.060885+00:00","temperatureC":2,"summary":"Cool","temperatureF":35}]
結果が返ってきました。
テンプレートではランダムな天気予報的なものが返ってくるようになってます。
しかし,このままではホスト側からはアクセスできません。
$ curl -kL http://localhost:5000/WeatherForecast
curl: (52) Empty reply from server
$ curl -kL https://localhost:5001/weatherforecast
curl: (35) gnutls_handshake() failed: The TLS connection was non-properly terminated.
Dockerコンテナ内のサービスが localhost
や 127.0.0.1
で LISTEN してるとホストからアクセスできません。
0.0.0.0
で LISTEN にする必要があります。
Properties/launchSettings.json で設定している箇所を書き換えます。
- "applicationUrl": "https://localhost:5001;http://localhost:5000",
+ "applicationUrl": "https://0.0.0.0:5001;http://0.0.0.0:5000",
ついでに,https へのリダイレクトも止めます。
Startup.fs の以下の行を削除します。
- app.UseHttpsRedirection() |> ignore
+ // app.UseHttpsRedirection() |> ignore
コンテナ側でサーバーを再起動すれば,ホストからもアクセスできるようになります。
$ curl http://localhost:5000/WeatherForecast
[{"date":"2020-01-12T12:24:14.3989892+00:00","temperatureC":53,"summary":"Bracing","temperatureF":127},{"date":"2020-01-13T12:24:14.3990139+00:00","temperatureC":36,"summary":"Warm","temperatureF":96},{"date":"2020-01-14T12:24:14.3990151+00:00","temperatureC":40,"summary":"Scorching","temperatureF":103},{"date":"2020-01-15T12:24:14.3990159+00:00","temperatureC":-16,"summary":"Bracing","temperatureF":4},{"date":"2020-01-16T12:24:14.3990167+00:00","temperatureC":27,"summary":"Freezing","temperatureF":80}]
その他
以下のコマンドでテンプレートの一覧が見られます。
$ dotnet new --list | grep F#
Console Application console [C#], F#, VB Common/Console
Class library classlib [C#], F#, VB Common/Library
Unit Test Project mstest [C#], F#, VB Test/MSTest
NUnit 3 Test Project nunit [C#], F#, VB Test/NUnit
NUnit 3 Test Item nunit-test [C#], F#, VB Test/NUnit
xUnit Test Project xunit [C#], F#, VB Test/xUnit
ASP.NET Core Empty web [C#], F# Web/Empty
ASP.NET Core Web App (Model-View-Controller) mvc [C#], F# Web/MVC
ASP.NET Core Web API webapi [C#], F# Web/WebAPI
F# が対応しているものは全て C# でも対応している感じですね。
つづく
次回は何かコード書いてみたいと思います。
https://qiita.com/dsudo/items/f773bf55b8a04b1a0e27